Пример #1
0
class DemoScreen(Screen):
    
    def __init__(self, disp, end_event, frame_getter):
        super(DemoScreen, self).__init__(disp)
        self.gaze = Circle(self.window, radius=50)
        self.gaze.fillColor = 'white'
        self.frame_getter = frame_getter
        self.min_time_over = False
        self.end_event = end_event
        
    def draw(self, debug_mode=False):
        frame = self.frame_getter()
        xy = (frame[u'avg'][u'x'],
              frame[u'avg'][u'y'])
        if xy == (0.0,0.0):
            xy = (-5000,-5000)

        self.gaze.pos = self.coords(xy)
        self.gaze.draw()
        
        if self.end_event.is_set():
            self.move_on_flag.set()
        
    def cleanup(self):
        wait(0.5)
        for _ in range(50):
            self.gaze.setRadius(self.gaze.radius - 1)
            self.gaze.draw()
            self.window.flip()
class DemoScreen(Screen):
    """ A screen to allow participants to mess around with eye tracking while they wait for the other participants to
        finish instructions and calibration.
    """
    
    def __init__(self, disp, end_event, frame_getter):
        super(DemoScreen, self).__init__(disp)
        self.gaze = Circle(self.window, radius=50)
        self.gaze.fillColor = 'white'
        self.frame_getter = frame_getter
        self.min_time_over = False
        self.end_event = end_event
        
    def draw(self, debug_mode=False):
        frame = self.frame_getter()
        xy = (frame[u'avg'][u'x'],
              frame[u'avg'][u'y'])
        if xy == (0.0, 0.0):
            xy = (-5000, -5000)

        self.gaze.pos = self.coords(xy)
        self.gaze.draw()
        
        if self.end_event.is_set():
            self.move_on_flag.set()
        
    def cleanup(self):
        wait(0.5)
        for _ in range(50):
            self.gaze.setRadius(self.gaze.radius - 1)
            self.gaze.draw()
            self.window.flip()
 def draw(self, location):
     y = 0
     if location == "left":
         x = int(win_width * -0.25)
         left_targ = Circle(disp,
                            pos=(x, y),
                            radius=self.radius,
                            edges=32,
                            lineColor=self.color,
                            fillColor=self.color)
         left_targ.draw()
     if location == "right":
         x = int(win_width * 0.25)
         right_targ = Circle(disp,
                             pos=(x, y),
                             radius=self.radius,
                             edges=32,
                             lineColor=self.color,
                             fillColor=self.color)
         right_targ.draw()
Пример #4
0
class WaitScreen(EventInstructionsScreen):
    
    def __init__(self, disp, text, end_event):
        super(EventInstructionsScreen, self).__init__(disp, text)
        self.move_on_flag = end_event
        self.indicator = Circle(self.window, radius=10)
        self.mouse = Mouse()
        self.ticker = 0
        self.ticker_unit = 2*pi/30
        self.ticker_max = 2*pi
        self.indicator_dist = 15
        
    def draw(self, debug_mode=False):
        self.instructions_text.draw()
        mouse_pos = self.mouse.getPos()
        x = mouse_pos[0] + self.indicator_dist*cos(self.ticker)
        y = mouse_pos[1] + self.indicator_dist*sin(self.ticker)
        self.indicator.pos = (x,y)
        self.indicator.draw()
        self.ticker += self.ticker_unit
        if self.ticker > self.ticker_max:
            self.ticker = 0
def draw_overview_target(win, level, target_pos, text_pos,
                         mouse_clicks_all_levels):
    target = ImageStim(win, 'target.png', size=420, pos=target_pos)
    level_text = TextStim(win,
                          text=f'Level {level}',
                          height=35,
                          color=(0.2, 0.2, 0.8),
                          pos=text_pos)

    target.draw()
    level_text.draw()

    target_x, target_y = target_pos
    curr_level_mouse_clicks = mouse_clicks_all_levels[level - 1]

    for target_hit_pos in curr_level_mouse_clicks:
        if target_hit_pos['mouse_in_target']:
            circle = Circle(win,
                            radius=5,
                            fillColor='yellow',
                            lineColor='yellow')
            circle.setPos((target_hit_pos['mouse_x'] + target_x,
                           target_hit_pos['mouse_y'] + target_y))
            circle.draw()
Пример #6
0
def main():
    groups = create_stim_sequence(BLOCK1, BLOCK2, BLOCK3, TRIALREPEATS)
    print groups

    disp = Window(size=SIZE,
                  monitor=MON,
                  units='deg',
                  color=BACKCOL,
                  screen=1,
                  fullscr=True)

    mouse = Mouse()

    fixmark = Circle(disp, radius=0.05, edges=32, pos=CENTER, lineColor=FIXCOL)

    images = []

    for item in CIRCLES.keys():
        image = ImageStim(disp,
                          image=CIRCLES[item][1],
                          pos=CIRCLES[item][0],
                          size=CIRCLES[item][3])
        images.append(image)

    fixmark.draw()
    draw_group(images)
    disp.flip()

    while True:
        button = mouse.getPressed()
        if button[0]:
            break

    for item in groups:
        flashes = []
        for i in item:
            flash = ImageStim(disp,
                              image=CIRCLES[i][2],
                              pos=CIRCLES[i][0],
                              size=CIRCLES[i][3])
            flashes.append(flash)
        fixmark.draw()
        draw_group(images)
        draw_group(flashes)
        disp.flip()
        wait(FLASH)
        fixmark.draw()
        draw_group(images)
        wait(PAUSE)
        disp.flip()

    disp.close()
Пример #7
0
         win,
         text=
         """Practice Block. \n\nUse the left mouse button to agree with the aid's decision or the right mouse button to disagree with the decision.""",
         wrapWidth=25,
         units='deg',
         pos=[0, 8],
         height=1,
         color='White')
 megchoice.draw()
 # Practice Block
 win.flip()
 waitKeys()
 win.mouseVisible = True
 megprac.draw()
 meg.draw()
 startButton.draw()
 win.flip()
 while myMouse.isPressedIn(startButton) == False:
     pass
 for trial in range(startPracticeTrials, endPracticeTrials):
     win.mouseVisible = False
     #Create the Aid's response
     (signal, autoResp, StimLength) = aidResponse(.15, .95)  #easy, low FA
     wait(.5)
     #Trial begins with the onset of pointers
     trialStart = clock.getTime()
     myMouse.clickReset()
     background.draw()
     #Draw target
     targpos = [random.uniform(-1, 1), random.uniform(-1, 1)]
     target = Rect(win,
class DetectPupilsScreen(Screen):
    """ Screen which lets subjects see where they should move their head to get the best calibration.
    """
    
    def __init__(self, disp, text, config_dict, pupil_coords_getter, seconds_to_ok):
        super(DetectPupilsScreen, self).__init__(disp)
        self.continue_button.pos = (0.0, 0.0)
        self.pupil_coords_getter = pupil_coords_getter
        cfg = config_dict[u'detect_pupils_screen']
        self.in_range_ctr = 0
        fps = self.window.getActualFrameRate()
        if fps is None:
            fps = 60
        self.ctr_max = fps*seconds_to_ok
        
        self.detect_pupils_instructions = TextStim(
                self.window,
                text=text,
                pos=self.coords((self.x_cfg_2_pix(cfg[u'text'][u'x']),
                                 self.y_cfg_2_pix(cfg[u'text'][u'y'])
                                 )),
                wrapWidth=self.x_cfg_2_pix(cfg[u'text'][u'width']),
                height=cfg[u'text'][u'font_size']
                )
                                
        self.lefteye = []
        self.lefteye.append(Circle(self.window, radius=50))
        self.lefteye[-1].fillColor = 'white'
        self.lefteye.append(Circle(self.window, radius=25))
        self.lefteye[-1].fillColor = 'black'
        
        self.riteeye = []
        self.riteeye.append(Circle(self.window, radius=50))
        self.riteeye[-1].fillColor = 'white'
        self.riteeye.append(Circle(self.window, radius=25))
        self.riteeye[-1].fillColor = 'black'
        
#         self.ok_indicator = RadialStim(
#                 self.window, tex='none', mask='gauss', pos=(0,0),
#                 size=(1000,1000), color=[0,0,0.5], opacity=0.5
#                 )

        self.ok_indicator = Circle(
                self.window, radius=(350, 200), fillColor='palegreen',
                opacity=0.05, lineColor=None
                )
        
        self.grid = []
        for x, y in self.window.calib_points_coords:
            self.grid.append(Circle(self.window,
                                    radius=5,
                                    pos=self.coords((x, y)),
                                    lineColor=None,
                                    fillColor='green'
                                    ))

    def draw(self, debug_mode=False):
        
        ((leftx, lefty), (ritex, ritey)) = self.pupil_coords_getter()
        
        leftx *= self.window.hres
        lefty *= self.window.vres
        ritex *= self.window.hres
        ritey *= self.window.vres
        
        if leftx == 0.0 or lefty == 0.0:
            leftx, lefty = (-5000, -5000)
        if ritex == 0.0 or ritey == 0.0:
            ritex, ritey = (-5000, -5000)
        for circle in self.lefteye:
            circle.pos = self.coords((leftx, lefty))
        for circle in self.riteeye:
            circle.pos = self.coords((ritex, ritey))

        if self.ok_indicator.contains(self.lefteye[0].pos) and self.ok_indicator.contains(self.riteeye[0].pos):
            self.in_range_ctr += 1
            op = self.ok_indicator.opacity + 0.03
            self.ok_indicator.opacity = min(op, 0.65)
        else:
            op = self.ok_indicator.opacity - 0.03
            self.ok_indicator.opacity = max(op, 0.05)

        if (self.in_range_ctr >= self.ctr_max) or debug_mode:
            self.continue_button.clickable = True

        # draw commands
        for thing in self.grid:
            thing.draw()
        self.ok_indicator.draw()
        self.detect_pupils_instructions.draw()
        self.continue_button.draw()

        for circle in self.lefteye:
            circle.draw()
        for circle in self.riteeye:
            circle.draw()
class ContribScreen(Screen):
    """ This screen lets users select their contribution.
    """
    
    def __init__(self,
                 disp,
                 text,
                 config_dict,
                 gaze_pos_getter=None,
                 width=None,
                 height=None,
                 margin=None,
                 font_size=None,
                 choice_font_size=100,
                 origin=None
                 ):
        super(ContribScreen, self).__init__(disp)
        cfg = config_dict[u'contrib_screen']
        self.gaze_pos_getter = gaze_pos_getter
        self.instr_text_preformat = text
        self.contrib_choice = '__'
        self.mouseover_threshold = 0
        self.choice_coords = []
        if width is not None:
            self.width = width
        else:
            self.width = self.window.hres
        if height is not None:
            self.height = height
        else:
            self.height = self.window.vres
        if margin is not None:
            self.margin = margin
        else:
            self.margin = self.window.margin
        if origin is not None:
            self.origin = origin
        if font_size is None:
            font_size = config_dict[u'contrib_screen'][u'text'][u'font_size']
        
        self.contrib_choices = self.gen_contrib_choices(
                cfg[u'nrows'], cfg[u'ncols'], font_size=choice_font_size
                )
        self.contrib_instructions = TextStim(
                self.window, height=font_size,
                text=self.instr_text_preformat.format(self.contrib_choice),
                pos=self.coords((self.x_cfg_2_pix(cfg[u'text'][u'x']),
                                 self.y_cfg_2_pix(cfg[u'text'][u'y'])
                                 )),
                wrapWidth=self.w_cfg_2_pix(cfg[u'text'][u'width'])
                )
        
        self.gaze = Circle(self.window, radius=5)
        self.gaze.fillColor = 'red'

    def draw(self, debug_mode=False): 
        mouse_x, mouse_y = self.mouse.getPos()
        for text_stim in self.contrib_choices:
            if xydist((mouse_x, mouse_y), text_stim.pos) < self.mouseover_threshold:
                text_stim.color = 'darkorange'
                if self.mouse.getPressed()[0]:
                    self.contrib_choice = text_stim.text
                    self.contrib_instructions.setText(self.instr_text_preformat.format(self.contrib_choice))
                    self.continue_button.clickable = True
            else:
                text_stim.color = 'white'
            text_stim.draw()
        self.continue_button.draw()
        self.contrib_instructions.draw()
        if self.gaze_pos_getter is not None:
            self.gaze.pos = self.coords(self.gaze_pos_getter())
            self.gaze.draw()
        
    def cleanup(self):
        self.continue_button.clickable = False
        self.contrib_instructions.setText(self.instr_text_preformat.format('__'))
        self.move_on_flag.clear()
        
    def gen_contrib_choices(self, nrows, ncols, font_size):
        h_spacing = (self.width - 2*self.margin)/(ncols-1)
        v_spacing = h_spacing
        '''OR: v_spacing = (self.height - 2*self.margin)/(nrows-1)'''
        self.mouseover_threshold = min(h_spacing, v_spacing)/4
        contrib_choices = []
        for i in range(0, nrows*ncols):
            xpos = self.margin + (i % ncols)*h_spacing
            
            '''
            To move the array to the bottom of the page:
            ypos = self.height - self.margin - (nrows-floor(1.0*i/ncols)-1)*v_spacing
            '''
            ypos = floor(1.0*i/ncols)*v_spacing + self.margin
            '''
            1.0*i/ncols gives us a floating-point number. Without the 1.0, python 
            interprets this as int-division and truncates. I could have exploited 
            this for slightly simpler code but it is really stupid that it works 
            that way and who knows what bugs could pop up by relying on something 
            that is in my opinion a bug?
            We take the floor of that number to give us a "row index." We multiply
            this number by the vertical spacing.
            '''
            
            if i < 10:
                temp = ' {} '.format(i)
            else:
                temp = '{}'.format(i)
            contrib_choices.append(TextStim(win=self.window,
                                            text=temp,
                                            pos=self.coords((xpos, ypos)),
                                            height=font_size))
            self.choice_coords.append((xpos, ypos))
        return contrib_choices
Пример #10
0
class DetectPupilsScreen(Screen):
    
    def __init__(self, disp, text, config_dict, pupil_coords_getter, seconds_to_ok):
        super(DetectPupilsScreen, self).__init__(disp)
        self.continue_button.setPos((0.0,0.0))
        self.pupil_coords_getter = pupil_coords_getter
        cfg = config_dict[u'detect_pupils_screen']
        self.in_range_ctr = 0
        fps = self.window.getActualFrameRate()
        self.ctr_max = fps*seconds_to_ok
        
        self.detect_pupils_instructions = TextStim(
                self.window,
                text=text,
                pos=self.coords((self.x_cfg_2_pix(cfg[u'text'][u'x']),
                               self.y_cfg_2_pix(cfg[u'text'][u'y'])
                               )),
                wrapWidth=self.x_cfg_2_pix(cfg[u'text'][u'width']),
                height=cfg[u'text'][u'font_size']
                )
                                
        self.lefteye = []
        self.lefteye.append(Circle(self.window, radius=50))
        self.lefteye[-1].fillColor='white'
        self.lefteye.append(Circle(self.window, radius=25))
        self.lefteye[-1].fillColor='black'
        
        self.riteeye = []
        self.riteeye.append(Circle(self.window, radius=50))
        self.riteeye[-1].fillColor='white'
        self.riteeye.append(Circle(self.window, radius=25))
        self.riteeye[-1].fillColor='black'
        
#         self.ok_indicator = RadialStim(
#                 self.window, tex='none', mask='gauss', pos=(0,0),
#                 size=(1000,1000), color=[0,0,0.5], opacity=0.5
#                 )

        self.ok_indicator = Circle(
                self.window, radius=(350,200), fillColor='palegreen', 
                opacity=0.05, lineColor=None
                )
        
        self.grid = []
        for x, y in self.window.calib_points_coords:
            self.grid.append(Circle(self.window,
                                    radius=5,
                                    pos=self.coords((x, y)),
                                    lineColor=None,
                                    fillColor='green'
                                    ))

        
    def draw(self, debug_mode=False):
        
        ((leftx,lefty),(ritex,ritey)) = self.pupil_coords_getter()
        
        leftx *= self.window.hres
        lefty *= self.window.vres
        ritex *= self.window.hres
        ritey *= self.window.vres
        
        if leftx == 0.0 or lefty == 0.0:
            leftx, lefty = (-5000,-5000)
        if ritex == 0.0 or ritey == 0.0:
            ritex, ritey = (-5000,-5000)
        for circle in self.lefteye:
            circle.pos = self.coords((leftx,lefty))
        for circle in self.riteeye:
            circle.pos = self.coords((ritex,ritey))
        
#         ldist = xydist([leftx,lefty], (self.window.hres/2,self.window.vres/2))
#         rdist = xydist([ritex,ritey], (self.window.hres/2,self.window.vres/2))
#         if ldist+rdist < self.window.vres/2:
#             self.in_range_ctr += 1

        if (self.ok_indicator.contains(self.lefteye[0].pos) and
            self.ok_indicator.contains(self.riteeye[0].pos)
            ):
            self.in_range_ctr += 1
            op = self.ok_indicator.opacity + 0.03
            self.ok_indicator.opacity = min(op, 0.65)
        else:
            op = self.ok_indicator.opacity - 0.03
            self.ok_indicator.opacity = max(op, 0.05)
#         
#         
#         if missed_flag:
#             temp = self.ok_indicator.color * 0.95
#             temp[2] = 0.5
#             temp[0] = 0
#         else:
#             ratio = self.window.vres/(3*(ldist+rdist))
#             if ratio > 1:
#                 ratio = 1
#             temp = [0, ratio, 0.5]
#  
#         self.ok_indicator.color = temp

        if ((self.in_range_ctr >= self.ctr_max) or 
            debug_mode
            ):
            self.continue_button.clickable = True

        # draw commands
        for thing in self.grid:
            thing.draw()
        self.ok_indicator.draw()
        self.detect_pupils_instructions.draw()
        self.continue_button.draw()

        for circle in self.lefteye:
            circle.draw()
        for circle in self.riteeye:
            circle.draw()
Пример #11
0
class FeedbackScreen(Screen):
    
    # This should not be messed with, we want to maintain between-
    # subject counterbalancing, but not change things within-subject.
    reversed = choice([True, False])
    
    def __init__(self,
                 disp,
                 num_players,
                 config_dict,
                 gaze_pos_getter=None,
                 width=None,
                 height=None,
                 margin=None,
                 font_size=None,
                 col_x_list=[],
                 AOIs=False):
        super(FeedbackScreen, self).__init__(disp)
        self.gaze_pos_getter = gaze_pos_getter
        self.continue_button.clickable = True
        
        cfg = config_dict[u'feedback_screen']
        if width is not None:
            self.width = width
        else:
            self.width = self.window.hres
        if height is not None:
            self.height = height
        else:
            self.height = self.window.vres
        if margin is not None:
            self.margin = margin
        else:
            self.margin = self.window.margin
        if font_size is not None:
            self.font_size = font_size
        else:
            self.font_size = config_dict[u'feedback_screen'][u'font_size']
        self.col_x_list = []
        if col_x_list == []:
            self.col_x_list.append(
                    self.x_cfg_2_pix(
                            config_dict[u'feedback_screen'][u'left_col_x']
                    ))
            self.col_x_list.append(
                    self.x_cfg_2_pix(
                            config_dict[u'feedback_screen'][u'midd_col_x']
                    ))
            self.col_x_list.append(
                    self.x_cfg_2_pix(
                            config_dict[u'feedback_screen'][u'rite_col_x']
                    ))
            del col_x_list
        if FeedbackScreen.reversed:
            self.col_x_list.reverse()
        
        self.gaze = Circle(self.window, radius=5)
        self.gaze.fillColor = 'red'
        
        self.nrows = num_players + 3
        self.SUMROWINDEX = self.nrows - 2
        self.AVGROWINDEX = self.nrows - 1
        
        row_spacing = (self.height - 2*self.margin)/(self.nrows-1)
        
        
        
        self.contr_col = []
        self.label_col = []
        self.payof_col = []
        
        for i in range(self.nrows):
            y = self.window.margin + i*row_spacing
            temp_contr = TextStim(self.window, height=self.font_size)
            temp_label = TextStim(self.window, height=self.font_size)
            temp_payof = TextStim(self.window, height=self.font_size)
            if i == 0:
                temp_contr.setText(cfg[u'contributions'])
                temp_label.setText(cfg[u'players'])
                temp_payof.setText(cfg[u'payoffs'])
            else:
                temp_contr.setText('xx')
                temp_payof.setText('xx')
                if i == 1:
                    temp_label.setText(cfg[u'you'])
                elif i <= num_players:
                    temp_label.setText(cfg[u'others'][i-2])
                elif i == self.SUMROWINDEX:
                    temp_label.setText(cfg[u'sum'])
                elif i == self.AVGROWINDEX:
                    temp_label.setText(cfg[u'average'])
                else:
                    logging.error('Error in FeedbackScreen.__init__(). Wrong number of rows?')
            temp_contr.setPos(self.coords((self.col_x_list[0], y)))
            self.contr_col.append(temp_contr)
            temp_label.setPos(self.coords((self.col_x_list[1], y)))
            self.label_col.append(temp_label)
            temp_payof.setPos(self.coords((self.col_x_list[2], y)))
            self.payof_col.append(temp_payof)
            
            self.AOIs = []
            if AOIs:
                for _ in range(3):
                    self.AOIs.append(Rect(self.window,
                                          width=400,
                                          height=280,
                                          lineColor='slateblue',
                                          fillColor='steelblue'))
                self.AOIs[-1].setPos(self.contr_col[-1].pos)
                self.AOIs[-2].setPos(self.label_col[-1].pos)
                self.AOIs[-3].setPos(self.payof_col[-1].pos)
        
                
    def draw(self, debug_mode=False):
        if getAbsTime() - self.t0 > 30:
            self.move_on_flag.set()
            
        if self.AOIs != [] and self.gaze_pos_getter is not None:
            self.gaze.pos = self.coords(self.gaze_pos_getter())
            for shape in self.AOIs:
                if shape.contains(self.gaze.pos):
                    shape.setFillColor('slateblue')
                else:
                    shape.setFillColor('steelblue')
            for shape in self.AOIs:
                shape.draw()
            self.gaze.draw()
            
        
        for i in range(self.nrows):
            self.label_col[i].draw()
            self.contr_col[i].draw()
            self.payof_col[i].draw()
        self.continue_button.draw()
            
    def cleanup(self):
        self.move_on_flag.clear()
            
    def update_info(self, contr_avg, payoff_avg, contr_sum, payoff_sum, my_contr, my_payoff, other_contr=[], other_payoff=[]):
        # This bit randomizes the order that the other players are
        # presented in on the feedback screen. Not yet tested to
        # make sure it works, but it should. Only matters if N > 2.
#         if len(other_contr) > 1:
#             indices = []
#             for i in range(len(other_contr)):
#                 indices.append(i)
#             shuffle(indices)
#             temp_contr = other_contr[:]
#             temp_payoff = other_payoff[:]
#             for i in range(len(indices)):
#                 other_contr[i] = temp_contr[indices[i]]
#                 other_payoff[i] = temp_payoff[indices[i]]

        self.update_col(self.contr_col, contr_avg, contr_sum, my_contr, other_contr)
        self.update_col(self.payof_col, payoff_avg, payoff_sum, my_payoff, other_payoff)
    
    def update_col(self, col, avg, sum_, mine, others):
#         avg = str(avg).replace('.',',')
        avg = '{:n}'.format(avg)
        sum_ = '{:n}'.format(sum_)
        mine = '{:n}'.format(mine)
        col[self.AVGROWINDEX].setText(avg)
        col[self.SUMROWINDEX].setText(sum_)
        col[1].setText(mine)
        for i in range(len(others)):
            other = '{:n}'.format(others[i])
            col[i+2].setText(other)
class CalibratableWindow(Window):


    def __init__(self,
                 num_calib_points=9,
                 margin=100,
                 **kwargs
                 ):
        super(CalibratableWindow, self).__init__(                                
                **kwargs
                )
        self.hres = int(self.size[0])
        self.vres = int(self.size[1])
        self.num_calib_points = num_calib_points
        self.margin = margin
        self.calib_points_coords = self.gen_calib_point_coords()
        
    def calibrate(self, et_comm):
        self.setMouseVisible(False)
        self.make_points()
        start_reply = et_comm.start_calibration(self.num_calib_points)
        if start_reply[u'statuscode'] == 403:
            et_comm.abort_calibration()
            et_comm.start_calibration(self.num_calib_points)
        calibration_obj={}
        for x,y in self.calib_points_coords:
            self.point_place(x,y)
            wait(0.750)            
            et_comm.start_calib_point(x,y)
            self.point_expand_contract(duration=1)
            calibration_obj = et_comm.end_calib_point()
            wait(0.250)
        self.setMouseVisible(True)
        return calibration_obj[u'values'][u'calibresult']

    def make_points(self):    
        self.outer_point = Circle(self, radius=25)
        self.outer_point.fillColor = 'white'
        self.outer_point.setPos((5000,5000))
        self.inner_point = Circle(self, radius=5)
        self.inner_point.fillColor = 'red'
        self.inner_point.setPos((5000,5000))
    
    def point_place(self, x, y):
        xy_tuple = self.tl2c((x,y))
        self.outer_point.setPos(xy_tuple)
        self.inner_point.setPos(xy_tuple)
        self.outer_point.draw()
        self.inner_point.draw()
        self.flip()
        
    def tl2c(self, coords_tuple):
        x = coords_tuple[0] - self.hres/2
        y = coords_tuple[1] - self.vres/2
        return (x, -y)
            
    def point_expand_contract(self, duration):
        start_time = getTime()
        ratio = 0
        while ratio < 1:
            ratio = (getTime()-start_time)/(duration*0.5)
            self.outer_point.setRadius(25+25*ratio)
            self.outer_point.draw()
            self.inner_point.draw()
            self.flip()
        while ratio < 2:
            ratio = (getTime()-start_time)/(duration*0.5)
            self.outer_point.setRadius(75-25*ratio)
            self.outer_point.draw()
            self.inner_point.draw()
            self.flip()
       
    def gen_calib_point_coords(self):
        if self.num_calib_points == 9:
            nrows = 3
            ncols = 3
        elif self.num_calib_points == 12:
            nrows = 3
            ncols = 4
        elif self.num_calib_points == 16:
            nrows = 4
            ncols = 4
        else:
            print('Unacceptable number of calibration points. '
                  'Please choose 9, 12, or 16. Defaulting to 9.')
            nrows = 3
            ncols = 3
            
        coord_list = []
        h_spacing = (self.hres - 2*self.margin)/(ncols-1)
        v_spacing = (self.vres - 2*self.margin)/(nrows-1)
        for row in range(nrows):
            for col in range(ncols):
                coord_list.append((col*h_spacing + self.margin, row*v_spacing + self.margin))
        shuffle(coord_list)
        return coord_list
Пример #13
0
# feedback screens
fbstim = {}
fbstim[0] = TextStim(disp, text='Incorrect', height=24, color=(1, 1, -1))
fbstim[1] = TextStim(disp, text='Correct', height=24, color=(-1, 1, -1))

# present instructions
inststim.draw()
disp.flip()
waitKeys(maxWait=float('inf'), keyList=None, timeStamped=True) # wait for key press




for cueside in ['left', "right"]:
# draw fixation mark and left and right boxes
    fixstim.draw()
    lboxstim.draw()
    rboxstim.draw()
    fixonset = disp.flip()
    wait(FIXTIME)

    fixstim.draw()
    lboxstim.draw()
    rboxstim.draw()
    cuestim[cueside].draw()
    cueonset = disp.flip()
    wait(CUETIME)
    fixstim.draw()
    lboxstim.draw()
    rboxstim.draw()
    cueoffset = disp.flip()
Пример #14
0
    class PsychopyCustomDisplay(pylink.EyeLinkCustomDisplay):
        """ Custom display for Eyelink eyetracker.
        Modified from the 'pylinkwrapper' package by Nick DiQuattro
        (https://github.com/ndiquattro/pylinkwrapper). All credits
        go to him.
        """
        def __init__(self, tracker, win, settings):
            """ Initializes PsychopyCustomDisplay object.

            """
            super().__init__()
            self.tracker = tracker
            self.win = win
            self.settings = settings  # from session
            self.txtcol = -1
            #self.__target_beep__ = sound.Sound(800, secs=.1)  # THIS WILL GIVE A SEGFAULT!
            #self.__target_beep__done__ = sound.Sound(1200, secs=.1)  # THIS WILL GIVE A SEGFAULT!
            #self.__target_beep__error__ = sound.Sound(400, secs=.1)  # THIS WILL GIVE A SEGFAULT!
            self.backcolor = self.win.color

            dot_size_pix = misc.deg2pix(
                self.settings['eyetracker'].get('dot_size'), self.win.monitor)
            self.targetout = Circle(self.win,
                                    pos=(0, 0),
                                    radius=dot_size_pix,
                                    fillColor='black',
                                    units='pix',
                                    lineColor='black')

            self.targetin = Circle(self.win,
                                   pos=(0, 0),
                                   radius=3,
                                   fillColor=0,
                                   lineColor=0,
                                   units='pix',
                                   opacity=0)
            win.flip()

        def setup_cal_display(self):
            txt = TextStim(
                self.win,
                text=
                "Please follow the dot. Try not to anticipate its movements.",
                pos=(0, 100),
                color='black',
                units='pix')

            txt.draw()
            self.targetout.draw()
            self.win.flip()

        def exit_cal_display(self):
            self.clear_cal_display()

        def clear_cal_display(self):
            self.setup_cal_display()

        def erase_cal_target(self):
            self.win.flip()

        def draw_cal_target(self, x, y):
            # Convert to psychopy coordinates
            x = x - (self.win.size[0] / 2)
            y = -(y - (self.win.size[1] / 2))

            # Set calibration target position
            self.targetout.pos = (x, y)
            self.targetin.pos = (x, y)

            # Display
            self.targetout.draw()
            self.targetin.draw()
            self.win.flip()

        def alert_printf(self, msg):
            print("alert_printf %s" % msg)

        def play_beep(self, beepid):
            if beepid == pylink.DC_TARG_BEEP or beepid == pylink.CAL_TARG_BEEP:
                self.__target_beep__.play()
            elif beepid == pylink.CAL_ERR_BEEP or beepid == pylink.DC_ERR_BEEP:
                self.__target_beep__error__.play()
            else:  # CAL_GOOD_BEEP or DC_GOOD_BEEP
                self.__target_beep__done__.play()

        def get_input_key(self):
            ky = []
            v = event.getKeys()
            for key in v:
                pylink_key = None
                if len(key) == 1:
                    pylink_key = ord(key)
                elif key == "escape":
                    pylink_key = pylink.ESC_KEY
                elif key == "return":
                    pylink_key = pylink.ENTER_KEY
                elif key == "pageup":
                    pylink_key = pylink.PAGE_UP
                elif key == "pagedown":
                    pylink_key = pylink.PAGE_DOWN
                elif key == "up":
                    pylink_key = pylink.CURS_UP
                elif key == "down":
                    pylink_key = pylink.CURS_DOWN
                elif key == "left":
                    pylink_key = pylink.CURS_LEFT
                elif key == "right":
                    pylink_key = pylink.CURS_RIGHT
                else:
                    print(f'Error! :{key} is not a used key.')
                    return

                ky.append(pylink.KeyInput(pylink_key, 0))

            return ky

        def record_abort_hide(self):
            pass

        def setup_image_display(self, width, height):

            self.size = (width / 2, height / 2)
            self.clear_cal_display()
            self.last_mouse_state = -1

            # Create array to hold image data later
            if self.rgb_index_array is None:
                self.rgb_index_array = np.zeros((self.size[1], self.size[0]),
                                                dtype=np.uint8)

        def exit_image_display(self):
            self.clear_cal_display()

        def image_title(self, text):
            # Display or update Pupil/CR info on image screen
            if self.imagetitlestim is None:
                self.imagetitlestim = TextStim(
                    self.window,
                    text=text,
                    pos=(0, self.window.size[1] / 2 - 15),
                    height=28,
                    color=self.txtcol,
                    alignHoriz='center',
                    alignVert='top',
                    wrapWidth=self.window.size[0] * .8,
                    units='pix')
            else:
                self.imagetitlestim.setText(text)

        def exit_image_display(self):
            self.clear_cal_display()

        def draw_image_line(self, width, line, totlines, buff):
            # Get image info for each line of image
            for i in range(width):
                self.rgb_index_array[line - 1, i] = buff[i]

            # Once all lines are collected turn into an image to display
            if line == totlines:
                # Make image
                image = scipy.misc.toimage(self.rgb_index_array,
                                           pal=self.rgb_pallete,
                                           mode='P')
                # Resize Image
                if self.imgstim_size is None:
                    maxsz = self.sres[0] / 2
                    mx = 1.0
                    while (mx + 1) * self.size[0] <= maxsz:
                        mx += 1.0
                    self.imgstim_size = int(self.size[0] * mx), int(
                        self.size[1] * mx)
                image = image.resize(self.imgstim_size)

                # Save image as a temporay file
                tfile = os.path.join(tempfile.gettempdir(), '_eleye.png')
                image.save(tfile, 'PNG')

                # Need this for target distance to show up
                self.__img__ = image
                self.draw_cross_hair()
                self.__img__ = None

                # Create eye image
                if self.eye_image is None:
                    self.eye_image = visual.ImageStim(self.window,
                                                      tfile,
                                                      size=self.imgstim_size,
                                                      units='pix')
                else:
                    self.eye_image.setImage(tfile)

                # Redraw the Camera Setup Mode graphics
                self.eye_image.draw()
                if self.imagetitlestim:
                    self.imagetitlestim.draw()

                # Display
                self.window.flip()

        def set_image_palette(self, r, g, b):
            # This does something the other image functions need
            self.clear_cal_display()
            sz = len(r)
            self.rgb_pallete = np.zeros((sz, 3), dtype=np.uint8)
            i = 0
            while i < sz:
                self.rgb_pallete[i:] = int(r[i]), int(g[i]), int(b[i])
                i += 1

        def dummynote(self):
            # Draw Text
            visual.TextStim(self.window,
                            text='Dummy Connection with EyeLink',
                            color=self.txtcol).draw()
            self.window.flip()

            # Wait for key press
            event.waitKeys()
            self.window.flip()