def __init__(self, window, prob, size, prefix='', pos=(0.0, 0.0), color_pos=(.65, .65, .65), color_neg=(-.65, -.65, -.65)): deg = prob * 360. self.piechart_pos = Pie(window, end=deg, fillColor=color_pos, pos=pos, size=size) self.piechart_neg = Pie(window, start=deg, end=360, fillColor=color_neg, pos=pos, size=size) txt = f'{prefix}{int(prob*100):d}%' self.text = TextStim(window, pos=(pos[0], pos[1] + size * 1.), text=txt, wrapWidth=size * 3, height=size * .75)
class Rating(): def __init__(self, win, description, labels, rating_file): self.win = win self.rating_file = rating_file self.description = TextStim(win, text=description, height=0.05, pos=(0, 0.5), units='norm', color=(0, 0, 0), colorSpace='rgb255') if len(labels) == 7: self.rating_scale = RatingScale(win, scale=None, labels=labels, tickMarks=[1, 2, 3, 4, 5, 6, 7], pos=(0, 0), stretch=3, textSize=0.8, textColor='Black', lineColor='Black', showValue=False, showAccept=False) else: self.rating_scale = RatingScale(win, scale=None, labels=labels, pos=(0, 0), stretch=3, textSize=0.8, textColor='Black', lineColor='Black', showValue=False, showAccept=False) self.button = Button(win, (0, -0.5), width=0.1, height=0.05, name='button_rating', text='确认') def run(self): while self.button.state != self.button.END: self.description.draw() self.rating_scale.draw() self.button.process() self.button.draw() self.win.flip() def save(self): self.rating_file.write('Rating: ' + str(self.rating_scale.getRating()) + '\n') self.rating_file.write('Decision Time: ' + str(self.rating_scale.getRT()) + '\n') choice_history = self.rating_scale.getHistory() self.rating_file.write('Choice History:\n(choice\ttime)\n') for i in choice_history: self.rating_file.write(str(i[0]) + '\t' + str(i[1]) + '\n') self.rating_file.write('\n')
def feedback(correct, window): """ Shows feedback (Correct! or Wrong!) after each test """ feedback_text = None color = None if correct: feedback_text = "Correct!" color = "Green" else: feedback_text = "Wrong" color = "Red" feedback = TextStim(win=window, text=feedback_text, pos=(0, 0), alignHoriz='center', alignVert='center', height=50, color=color) feedback.setAutoDraw(True) for frameN in range(60): window.flip() feedback.setAutoDraw(False) window.flip()
def __init__(self, win, warper): self.win = win self.warper = warper self.stimT = TextStim(self.win, text='Null warper', units = 'pix', pos=(0, -140), alignHoriz='center', height=20) self.bl = -win.size / 2.0 self.tl = (self.bl[0], -self.bl[1]) self.tr = win.size / 2.0 self.stims = [] self.degrees = 120 nLines = 12 for x in range(-nLines, nLines+1): t = GratingStim(win,tex=None,units='deg',size=[2,win.size[1]],texRes=128,color=foregroundColor, pos=[float(x) / nLines * self.degrees,0]) self.stims.append (t) for y in range (-nLines, nLines+1): t = GratingStim(win,tex=None,units='deg',size=[win.size[0],2],texRes=128,color=foregroundColor,pos=[0,float(y)/nLines * self.degrees]) self.stims.append (t) for c in range (1, nLines+1): t = Circle (win, radius=c * 10, edges=128, units='deg', lineWidth=4) self.stims.append (t) self.updateInfo() self.keys = key.KeyStateHandler() win.winHandle.push_handlers(self.keys) self.mouse = event.Mouse(win=self.win)
def display_text(self, text, keys=None, duration=None, **kwargs): """ Displays text on the window and waits for a key response. The 'keys' and 'duration' arguments are mutually exclusive. parameters ---------- text : str Text to display keys : str or list[str] String (or list of strings) of keyname(s) to wait for kwargs : key-word args Any (set of) parameter(s) passed to TextStim """ if keys is None and duration is None: raise ValueError("Please set either 'keys' or 'duration'!") if keys is not None and duration is not None: raise ValueError("Cannot set both 'keys' and 'duration'!") stim = TextStim(self.win, text=text, **kwargs) stim.draw() self.win.flip() if keys is not None: waitKeys(keyList=keys) if duration is not None: core.wait(duration)
def __init__(self, win, pos, size, session, ori=0, hide=False, text=''): super(StimulusSetToPosition, self).__init__(win, pos=pos, size=size, session=session, ori=ori, hide=hide) lw = self.session.deg2pix(self.config.get('cross', 'linewidth')) self.cross = Cross( self.screen, self.size, pos=self.pos, lineColor=self.config.get('cross', 'color'), lineWidth=lw, ori=ori, ) self.text_stimulus = TextStim( self.screen, 'size left', pos=[self.pos[0], self.pos[1] + 0.1 * self.size], height=self.size * 0.05, ori=self.ori, color='green') self.checkerboard.contrast = 0
def __enter__(self): from psychopy.visual import GratingStim # eats some time from psychopy.visual import TextStim win = self.window.instance self.textstim = TextStim(win, text='') # for some reason x, y were swapped.. # this may happen if monitor setup was portrait mode instead of landscape. width, height = misc.pix2deg(win.size, win.monitor) if self.component.width: width = self.component.width self.instance = GratingStim( win=win, tex='sin', units='deg', size=(height, width) # size = misc.pix2deg(win.size, win.monitor) ) tf = self.component.tfrequency self.contrast_factor = tf * np.pi * (2 / self.component.ct_period) self.opacity_factor = tf * np.pi * (2 / self.component.op_period) try: self.interval = self.window.get_isi() except Exception as e: raise ServiceRuntimeException( 'Could not acquire window object. Please try again') return self
def set_screen(): # screen properties global win, start_text, left_label, right_label, center_disp, instruction_page, left_bg, right_bg, ok_button, ok_text win = Window([1280, 1000], color='Black', fullscr=fullscreen, screen=0, units='pix', allowGUI=True) # 1280 1024 text_left = 'nein' text_right = 'ja' h_dist = 80 v_dist = -190 left_bg = Rect(win, fillColor='red', pos=[-h_dist, v_dist - 7], width=130, height=85) right_bg = Rect(win, fillColor='green', pos=[h_dist, v_dist - 7], width=130, height=85) left_label = TextStim(win, color='white', font='Verdana', text=text_left, pos=[-h_dist, v_dist], height=50, alignHoriz='center') right_label = TextStim(win, color='white', font='Verdana', text=text_right, pos=[h_dist, v_dist], height=50, alignHoriz='center') center_disp = TextStim(win, color='white', font='Arial', text='', height=55) instruction_page = TextStim(win, wrapWidth=1200, pos=[0, 35], height=28, font='Verdana', color=instruction_color) ok_button = Rect(win, fillColor='black', lineColor=instruction_color, pos=[0, -345], width=80, height=50) ok_text = TextStim(win, text='OK', bold=True, color=instruction_color, pos=(0, -345), height=30)
def EndExp(): exitPrompt = ("This concludes the session. Thank you for " "participating!\n\nPress Escape to quit") exitText = TextStim(self.window, exitPrompt, color='Black') exitText.draw(self.window) self.window.flip() waitKeys(keyList=['escape']) self.window.close()
class ImageScreen(Screen): def __init__(self, disp, text, text_width, image, image_size, text_pos=None, image_pos=None, wait_time=1, extra_image_stims=[] ): super(ImageScreen, self).__init__(disp, wait_time=wait_time) self.extra_image_stims = extra_image_stims self.wait_time = wait_time if self.wait_time == 0: self.continue_button.clickable = True if text_pos is None: _text_pos = self.coords(self.width/4, self.height/2) else: _text_pos = text_pos if image_pos is None: _image_pos = self.coords(3*self.width/4, self.height/2) else: _image_pos = image_pos self.text_stim = TextStim( win=self.window, text=text, pos=_text_pos, height=Screen.default_font_size, wrapWidth=text_width ) self.img_stim = ImageStim( win=self.window, image=image, pos=_image_pos, size=(image_size[0], image_size[1]) ) def draw(self, debug_mode=False): for img_stim in self.extra_image_stims: img_stim.draw() self.continue_button.draw() self.text_stim.draw() self.img_stim.draw() if not self.continue_button.clickable: if getAbsTime() - self.t0 > self.wait_time: self.continue_button.clickable = True def cleanup(self): for extra in self.extra_image_stims: del extra self.window.flip() self.window.flip() self.window.flip()
def __init__(self, mouse: Mouse, window: Window, text: str, keys: List[str]): super().__init__(mouse, window) self.keys = keys self.instruction_text = TextStim(window, text=text, color="black", height=30, pos=(0, 0))
def draw(self): """ Draws stimuli """ if self.phase == 0: stim = TextStim(self.session.win, 'Trial %i' % (self.trial_nr)) stim.draw() else: self.session.default_fix.draw() super().draw()
def __init__(self, win, description, labels, rating_file): self.win = win self.rating_file = rating_file self.description = TextStim(win, text=description, height=0.05, pos=(0, 0.5), units='norm', color=(0, 0, 0), colorSpace='rgb255') if len(labels) == 7: self.rating_scale = RatingScale(win, scale=None, labels=labels, tickMarks=[1, 2, 3, 4, 5, 6, 7], pos=(0, 0), stretch=3, textSize=0.8, textColor='Black', lineColor='Black', showValue=False, showAccept=False) else: self.rating_scale = RatingScale(win, scale=None, labels=labels, pos=(0, 0), stretch=3, textSize=0.8, textColor='Black', lineColor='Black', showValue=False, showAccept=False) self.button = Button(win, (0, -0.5), width=0.1, height=0.05, name='button_rating', text='确认')
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()
class TestTrial(Trial): """ Simple trial with text (trial x) and fixation. """ def __init__(self, session, trial_nr, phase_durations, txt=None, **kwargs): super().__init__(session, trial_nr, phase_durations, **kwargs) self.txt = TextStim(self.session.win, txt) def draw(self): """ Draws stimuli """ if self.phase == 0: self.txt.draw() else: self.session.default_fix.draw()
class CueTrial(Trial): def __init__(self, session, trial_nr, phase_durations, txt, **kwargs): super().__init__(session, trial_nr, phase_durations, **kwargs) self.txt = TextStim(self.session.win, txt, height=1, wrapWidth=300) def draw(self): if self.phase == 0: self.txt.draw() else: pass
def __init__(self, win, pos, size, color=(1,0,0)): self.screen = win self.fixation_stim1 = TextStim(win, '+', height=size) self.fixation_stim1.blendmode = 'avg'
def draw(self): """ Draws stimuli """ if self.phase == 0: if 'response' in self.log['event_type']: self.stop_phase() stim = TextStim(self.session.win, 'Trial %i' % (self.trial_nr)) stim.draw() else: self.session.default_fix.draw() super().draw()
class GambleInstructTrial(GambleTrial): def __init__(self, session, trial_nr, txt, bottom_txt=None, show_phase=0, keys=None, **kwargs): phase_durations = np.ones(12) * 1e-6 phase_durations[show_phase] = np.inf self.keys = keys super().__init__(session, trial_nr, phase_durations=phase_durations, **kwargs) txt_height = self.session.settings['various'].get('text_height') txt_width = self.session.settings['various'].get('text_width') self.text = TextStim(session.win, txt, pos=(0.0, 6.0), height=txt_height, wrapWidth=txt_width, color=(0, 1, 0)) if bottom_txt is None: bottom_txt = "Press any button to continue" self.text2 = TextStim(session.win, bottom_txt, pos=( 0.0, -6.0), height=txt_height, wrapWidth=txt_width, color=(0, 1, 0)) def get_events(self): events = Trial.get_events(self) if self.keys is None: if events: self.stop_phase() else: for key, t in events: if key in self.keys: self.stop_phase() def draw(self): if self.phase != 0: self.session.fixation_lines.setColor((1, -1, -1)) if self.phase < 9: super().draw() else: self.session.fixation_lines.draw() if self.phase == 10: self.choice_stim.draw() elif self.phase == 11: self.certainty_stim.draw() self.text.draw() self.text2.draw()
def Pause(self): """Pauses the task, and displays a message waiting for a spacebar input from the user before continuing to proceed. """ pauseMsg = "Experiment Paused\n\nPress '{}' to continue".format( self.pauseButton) pauseText = TextStim(self.window, text=pauseMsg, color='Black', height=40) pauseText.draw(self.window) self.window.flip() waitKeys(keyList=[self.pauseButton]) clearEvents()
class CertaintyStimulus(object): def __init__(self, window, response_size=(1, .5), fillColor=(1, 1, -1), *args, **kwargs): n_responses = 4 total_width = n_responses * \ response_size[0] + (n_responses - 1) * .1 * response_size[0] positions = -total_width / 2. + \ response_size[0]/2. + \ np.arange(n_responses) * 1.1 * response_size[0] positions = [(pos, 0) for pos in positions] self.rectangles = [ Rect(window, size=response_size, pos=positions[n], opacity=.5, fillColor=fillColor) for n in range(n_responses) ] self.stim_texts = [ TextStim(window, height=.45 * response_size[1], wrapWidth=.9 * response_size[0], pos=positions[n], color=(-1, -1, -1), text=n + 1) for n in range(n_responses) ] self.description_text = TextStim( window, pos=(0, 1.5 * response_size[1]), wrapWidth=response_size[0] * 8.8, text= 'How certain are you about your choice (1=very certain, 4= very uncertain)' ) def draw(self): for rect in self.rectangles: rect.draw() for txt in self.stim_texts: txt.draw() self.description_text.draw()
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 ShowPromptAndWaitForSpace(self, prompt, keylist=['space', 'escape']): ''' Show the prompt on the screen and wait for space, or the keylist specified returns the key pressed ''' keylist = [self.pauseButton, 'escape'] text = TextStim(self.window, prompt, color='Black') text.draw(self.window) self.window.flip() continueKey = waitKeys(keyList=keylist) if len(continueKey) != 0 and continueKey[0] == 'escape': self.logfile.write("Terminated early.") self.logfile.close() sys.exit() return continueKey
def test_init(self): #for win in [self.win, self.winpix]: m = CustomMouse(self.win, showLimitBox=True, autoLog=False) assert (m.leftLimit, m.topLimit, m.rightLimit, m.bottomLimit) == (-1, 1, 0.99, -0.98) assert m.visible == True assert m.showLimitBox == True assert m.clickOnUp == False m.getPos() m.draw() m.clickOnUp = m.wasDown = True m.isDownNow = False m.draw() m.getClicks() m.resetClicks() m.getVisible() m.setVisible(False) with pytest.raises(AttributeError): m.setPointer('a') m.setPointer(TextStim(self.win, text='x')) m = CustomMouse(self.winpix, autoLog=False) assert (m.leftLimit, m.topLimit, m.rightLimit, m.bottomLimit) == (-64.0, 128.0, 59.0, -118.0) assert m.visible == True assert m.showLimitBox == m.clickOnUp == False m.getPos()
class InstructionsScreen(Screen): def __init__(self, disp, text, font_size=40, wait_time=0): super(InstructionsScreen, self).__init__(disp, wait_time=wait_time) self.instructions_text = TextStim( disp, pos=(0,0), text=text, height=font_size, wrapWidth=self.w_cfg_2_pix(0.666) ) def draw(self, debug_mode=False): self.instructions_text.draw() def cleanup(self): self.window.flip() self.window.flip() self.window.flip()
def day2(self): day2_text = "The task for this session is similar to yesterday. " day2_text += "You will respond six additional sets of trials. " pressToContinue = TextStim(self.win, text="<press any key to continue>", pos=(0, -0.9), height=0.06, units="norm", alignHoriz="center") ready = self.makeTextStim(day2_text) ready.draw() pressToContinue.draw() win.flip() event.waitKeys()
def test_flip(self): good = TextStim(self.win, text='a', pos=(.5, .5), autoLog=False) b = BufferImageStim(self.win, stim=[good], autoLog=False) b.setFlipHoriz(True) assert b.flipHoriz == True b.setFlipVert(True) assert b.flipVert == True
def __init__(self, disp, text, input_prompt_list, correct_ans_list=None, extra_draw_list=[]): super(KeyboardInputScreen, self).__init__(disp) self.instructions_text = TextStim( disp, pos=(0, disp.vres*0.2), text=text, height=40, wrapWidth=self.w_cfg_2_pix(0.666) ) self.input_prompt_list = [] self.input_field_list = [] self.extra_draw_list = extra_draw_list height_list = [] for i in range(len(input_prompt_list)): height_list.append( disp.vres*-0.2*i/(len(input_prompt_list)-1) ) for index, text in enumerate(input_prompt_list): self.input_prompt_list.append(TextStim( disp, pos=(disp.hres*-0.2, height_list[index]), text=text, height=40, wrapWidth=disp.hres*0.5 )) self.input_field_list.append(button.Button( disp, pos=(disp.hres*0.2, height_list[index]), font_size=30, width=disp.hres*0.15, height=40, text_color='black', text='' )) self.active_input_field = None self.answer_list = [] self.correct_ans_list = correct_ans_list
def userResponse(response, done, qpos, image, multi): """ Function that will be called every time the user needs to press a key to pass to the next display - **Input**: :response: the user resonse (empty string at beginning) :done: boolean (True / False) -> False at beginning :qpos: text position for user response :image: the stimulus image :multi: multiple display ? integer (1, 2 or 3) """ # --------------------------------------- # # WHILE THE WELCOME MESSAGE IS NOT PASSED # # --------------------------------------- # while len(response) == 0: # while the user has not taped anything yet response = '' # the response written by the user - On commence avec une chaîne vide respstim = TextStim(disp, text='', pos=qpos, height=size) # stimulus texte qstim = ImageStim(disp, image=image) qstim.draw() # dessiner la question if multi >= 2: # at least 2 diferent stimuli qstim2.draw() if multi == 3: # 3 diferent stimuli qstim3.draw() disp.flip( ) # passer au screen au suivant -> on met la question par-dessus core.wait(loadTime ) # delay of 10 seconds before passing to the learning phase done = False # ----------------------------------- # # WHILE THE USER'S ANSWER IS NOT DONE # # Check for keypresses # # ----------------------------------- # while not done: # loop until done == True resplist = waitKeys(maxWait=float('inf'), keyList=None, timeStamped=True) key, presstime = resplist[ 0] # use only the first in the returned list of keypresses -> resplist[0] is the first element in the resplist list response += key #Ajouter la lettre tapée à la réponse done = True # set done to True qstim.draw() # réafficher la question stimulus respstim.draw() # réafficher la réponse au stimulus disp.flip() # update the monitor core.wait( loadTime) # add a little lag to avoid little freez and/or bug
def wait_for_scanner(win, keys:List[str] =["equal", "asciicircum"], msg:Optional[str]=None) -> TaskTime: """put up a message and wait for the scanner to send a trigger, return fliptime @param win - window to draw on @param keys - list of accpetaible keys, default ^ and = @param msg - message to show while waiting """ from psychopy.visual import TextStim from psychopy.event import waitKeys if not msg: msg=f'Get Ready!\nWaiting for the scanner' # previously aslo mentioned the keys we are wating for # \n{", ".join(keys)}' tx = TextStim(win, text=msg) tx.draw() win.flip() waitKeys(keyList=keys) return getTime()
def decideFeedback(on, humanResp, signal): # takes on/off condition, humanResp and signal and return trialACC and feedback image if on < 2: if humanResp == signal: trialACC = 1 feedback = TextStim(win, text="""+""", units='deg', pos=[0, 0], height=1, color='White') else: trialACC = 0 feedback = TextStim(win, text="""x""", units='deg', pos=[0, 0], height=1, color='Red') elif on == 2: if (autoResp == signal) and (humanResp == 0): trialACC = 1 feedback = TextStim(win, text="""+""", units='deg', pos=[0, 0], height=1, color='White') elif (autoResp != signal) and (humanResp == 1): trialACC = 1 feedback = TextStim(win, text="""+""", units='deg', pos=[0, 0], height=1, color='White') else: trialACC = 0 feedback = TextStim(win, text="""x""", units='deg', pos=[0, 0], height=1, color='Red') return (trialACC, feedback)
def makeTextStim(self, text, vertpos=0): return TextStim(self.win, text=text, wrapWidth=1.0, pos=(0.0, vertpos), alignHoriz="center", height=0.08, color="#FFFFFF", units="norm")
def __enter__(self): from psychopy.visual import ImageStim # eats some time from psychopy.visual import TextStim event.clearEvents() win = self.window.instance self.textstim = TextStim(win, text='') # image texture index order is iamge[y, x] self.instance = ImageStim( win=win, units='deg', #, filpVert=True, pos=self.component.position, size=self.component.size) #misc.pix2deg(win.size, win.monitor)*2) try: self.interval = self.window.get_isi() except Exception as e: raise ServiceRuntimeException( 'Could not acquire window object. Please try again') return self
class InstructionTrial(Trial): """pseudo trial to display text""" def __init__(self, mouse: Mouse, window: Window, text: str, duration: float): super().__init__(mouse, window) self.duration = duration self.instruction_text = TextStim( window, text=text, color="black", height=30, pos=(0, 0) ) def run(self): self.draw() self.window.flip() core.wait(self.duration) self.window.flip() def draw(self): self.instruction_text.draw(self.window)
def setup_text(self): self.scoretxt = TextStim(self.win, text="Total Points: ", font='Helvetica', alignHoriz='left', alignVert='top', units='norm', pos=(-1, 1), height=0.2, color=[178, 34, 34], colorSpace='rgb255', wrapWidth=2) self.targtxt = [] for targ in range(self.geom['numtargs']): self.targtxt.append(TextStim(self.win, pos=self.geom['target_centers'][targ], color='White', units='height', height=0.05, text=''))
def get_user_input(window, position, fontsize=50): """ Allows the user to type and see what they type on the screen (This is more annoying than it should be on Psychopy, but it works fine now so you shouldn't need to change it) """ input_name = "" user_input = TextStim(win=window, text=input_name, pos=position, height=fontsize) user_input.setAutoDraw(True) window.flip() while True: char = event.waitKeys()[0] if char.isalpha() and len(char) == 1: input_name += char if char == 'return': user_input.setAutoDraw(False) window.flip() return input_name if char == 'comma': # psychopy inexplicably doesn't respond to the backspace key, # so I use the '<' symbol instead input_name = input_name[:-1] user_input.text = input_name window.flip()
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 __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 __init__(self, disp, text, extra_commands, wait_time=1, txt_dict=None, cfg_dict=None): super(FlexibleResourcePresentationScreen, self).__init__(disp, wait_time) self.txt_dict = txt_dict self.cfg_dict = cfg_dict self.wait_time = wait_time if self.wait_time == 0: self.continue_button.clickable = True self.text_stim = TextStim( win=self.window, text=text, pos=self.coords((self.x_cfg_2_pix(0.25), self.y_cfg_2_pix(0.5))), height=Screen.default_font_size, wrapWidth=self.w_cfg_2_pix(0.4) ) self.extra_draw_stims = [] for command in extra_commands: if type(command) == str or type(command) == unicode: items = eval(command) for item in items: self.extra_draw_stims.append(item)
def __init__(self, disp, text, text_width, image, image_size, text_pos=None, image_pos=None, wait_time=1, extra_image_stims=None ): super(ImageScreen, self).__init__(disp, wait_time=wait_time) self.extra_image_stims = extra_image_stims if self.extra_image_stims is None: self.extra_image_stims = [] self.wait_time = wait_time if self.wait_time == 0: self.continue_button.clickable = True if text_pos is None: _text_pos = self.coords(self.width/4, self.height/2) else: _text_pos = text_pos if image_pos is None: _image_pos = self.coords(3*self.width/4, self.height/2) else: _image_pos = image_pos self.text_stim = TextStim( win=self.window, text=text, pos=_text_pos, height=Screen.default_font_size, wrapWidth=text_width ) self.img_stim = ImageStim( win=self.window, image=image, pos=_image_pos, size=(image_size[0], image_size[1]) )
class Display: def __init__(self, pars): self.win = initializers.setup_window() self.pars = pars self.geom = initializers.setup_geometry(self.win, self.pars) self.rotation_clocks = [None] * self.geom['numtargs'] self.type = ['default'] * self.geom['numtargs'] self.setup_sounds() self.setup_images() self.setup_text() def setup_sounds(self): self.cashsnd = Sound('resources/cash.wav') self.firesnd = Sound('resources/bbhit.wav') self.buzzsnd = Sound('resources/buzz.wav') def setup_images(self): self.notargs = [] self.gotargs = [] self.deftargs = [] self.bkimg = ImageStim(self.win, image='resources/pond.jpg', units='norm', size=(2.0, 2.0)) for targ in range(self.geom['numtargs']): self.notargs.append(ImageStim(self.win, image='resources/rfrog2.jpg', size=self.geom['target_size'], pos=self.geom['target_centers'][targ])) self.gotargs.append(ImageStim(self.win, image='resources/gfrog2.jpg', size=self.geom['target_size'], pos=self.geom['target_centers'][targ])) self.deftargs.append(ImageStim(self.win, image='resources/lilypad.jpg', size=self.geom['target_size'], pos=self.geom['target_centers'][targ])) # set initial target stims to be the defaults self.targets = [] for targ in self.deftargs: self.targets.append(targ) def setup_text(self): self.scoretxt = TextStim(self.win, text="Total Points: ", font='Helvetica', alignHoriz='left', alignVert='top', units='norm', pos=(-1, 1), height=0.2, color=[178, 34, 34], colorSpace='rgb255', wrapWidth=2) self.targtxt = [] for targ in range(self.geom['numtargs']): self.targtxt.append(TextStim(self.win, pos=self.geom['target_centers'][targ], color='White', units='height', height=0.05, text='')) def set_target_image(self, index, value='default'): if value == 'go': self.targets[index] = self.gotargs[index] elif value == 'no': self.targets[index] = self.notargs[index] elif value == 'default': self.targets[index] = self.deftargs[index] def set_target_text(self, index, value): self.targtxt[index].setText(value) def set_score(self, pts): self.scoretxt.setText('Total Points: ' + str(pts)) def onset(self, index, value): self.rotation_clocks[index] = Clock() self.type[index] = value def offset(self, index): self.rotation_clocks[index] = Clock() self.type[index] = 'default' def update(self): # for each target with clock running (i.e., rotating) ... for idx, clk in enumerate(self.rotation_clocks): if clk: rot_time = clk.getTime() rot_dur = self.pars['rot_dur'] if rot_time > rot_dur: rotfrac = -1 # rotation completed else: rotfrac = cos(pi * rot_time / self.pars['rot_dur']) # adjust target size to give illusion of rotation base_size = self.geom['target_size'] self.targets[idx].size = (abs(rotfrac) * base_size[0], base_size[1]) # set correct image on target based on rotation angle if rotfrac < 0: self.set_target_image(idx, self.type[idx]) def draw(self): self.update() self.bkimg.draw() self.scoretxt.draw() for stim in self.targets: stim.draw() for stim in self.targtxt: stim.draw() self.win.flip() def close(self): self.win.close()
# test for two monitors: import time from psychopy.visual import Window from psychopy.visual import TextStim from psychopy import event # create a Window create_win = lambda s: Window(size=(1280,1024), fullscr=True, monitor="testMonitor", winType='pyglet', screen=s) win1 = create_win(0) win2 = create_win(1) # draw some text on the Window txt = list() txt.append(TextStim(win1, text="This is screen 1")) txt.append(TextStim(win2, text="This is screen 2")) txt2 = TextStim(win2, pos=(0, -0.5), text="another text") [t.draw() for t in txt] win1.flip() event.waitKeys() win2.flip(clearBuffer=False) event.waitKeys() txt2.draw() win2.flip(clearBuffer=False) event.waitKeys()
pump = qmix.Pump(index=0, volumeUnit='mL', flowRateUnit='mL/s', syringeType='50 mL glass') print('Max. flow rate: .3%f %s' % (pump.maxFlowRate, pump.flowRateUnit)) win = Window() msg = ('Press one of the following keys: \n\n' ' F – Fill Syringe at 1 mL/s\n' ' E – Empty Syringe at 1 mL/s\n' ' A – Aspirate 1 mL at 1 mL/s\n' ' D – Dispense 1 mL at 1 mL/s\n' '\n' ' Q – Quit') t = TextStim(win, msg) event.clearEvents() while True: t.draw() win.flip() # Retrieve keypresses. The user can completely fill or empty the syringe, # or aspirate or dispense a small volume (1 mL) by pressing the # corresponding keys. # # When aspirating or dispensing, the code halts further script execution # until the pump operation has finished, and then immediately switches the # valve position (i.e., from inlet to outlet after aspiration, and from # outlet to inlet after dispense). During an experiment, this can ensure # a sharp(er) stimulus offset.
class FlexibleResourcePresentationScreen(Screen): def __init__(self, disp, text, extra_commands, wait_time=1, txt_dict=None, cfg_dict=None): super(FlexibleResourcePresentationScreen, self).__init__(disp, wait_time) self.txt_dict = txt_dict self.cfg_dict = cfg_dict self.wait_time = wait_time if self.wait_time == 0: self.continue_button.clickable = True self.text_stim = TextStim( win=self.window, text=text, pos=self.coords((self.x_cfg_2_pix(0.25), self.y_cfg_2_pix(0.5))), height=Screen.default_font_size, wrapWidth=self.w_cfg_2_pix(0.4) ) self.extra_draw_stims = [] for command in extra_commands: if type(command) == str or type(command) == unicode: items = eval(command) for item in items: self.extra_draw_stims.append(item) def draw(self, debug_mode=False): if not self.continue_button.clickable: if getAbsTime() - self.t0 > self.wait_time: self.continue_button.clickable = True self.continue_button.draw() self.text_stim.draw() for stim in self.extra_draw_stims: stim.draw() def painfully_clear_example(self, n): img = ImageStim( win=self.window, image='resources/worked_example/Slide{}.PNG'.format(n), pos=(0,200), size=(960,720) ) background = Rect( win=self.window, width=img.size[0]+10, height=img.size[1]+10, fillColor='white', lineColor=None, pos=img.pos ) return [background, img] def mini_contrib_screen(self): img = ImageStim( win=self.window, image='resources/contrib_screen.PNG', pos=self.coords((self.x_cfg_2_pix(0.75), self.y_cfg_2_pix(0.33))), size=(960, 540) ) background = Rect( win=self.window, width=img.size[0]+10, height=img.size[1]+10, fillColor='white', lineColor=None, pos=img.pos ) return [background, img] def mini_feedback_screen(self, n): if FeedbackScreen.reversed: img = 'resources/feedback/reversed/Slide{}.PNG'.format(n) else: img = 'resources/feedback/default/Slide{}.PNG'.format(n) image = ImageStim( win=self.window, image=img, pos=self.coords((self.x_cfg_2_pix(0.75), self.y_cfg_2_pix(0.33))), size=(960, 540) ) background = Rect( win=self.window, width=image.size[0]+10, height=image.size[1]+10, fillColor='white', lineColor=None, pos=image.pos ) return [background, image] def cleanup(self): self.window.flip() self.window.flip() self.window.flip()
class KeyboardInputScreen(Screen): def __init__(self, disp, text, input_prompt_list, correct_ans_list=None, extra_draw_list=[]): super(KeyboardInputScreen, self).__init__(disp) self.instructions_text = TextStim( disp, pos=(0, disp.vres*0.2), text=text, height=40, wrapWidth=self.w_cfg_2_pix(0.666) ) self.input_prompt_list = [] self.input_field_list = [] self.extra_draw_list = extra_draw_list height_list = [] for i in range(len(input_prompt_list)): height_list.append( disp.vres*-0.2*i/(len(input_prompt_list)-1) ) for index, text in enumerate(input_prompt_list): self.input_prompt_list.append(TextStim( disp, pos=(disp.hres*-0.2, height_list[index]), text=text, height=40, wrapWidth=disp.hres*0.5 )) self.input_field_list.append(button.Button( disp, pos=(disp.hres*0.2, height_list[index]), font_size=30, width=disp.hres*0.15, height=40, text_color='black', text='' )) self.active_input_field = None self.answer_list = [] self.correct_ans_list = correct_ans_list def draw(self, debug_mode=False): self.continue_button.clickable = True key_list = getKeys() if self.active_input_field is not None: for key in key_list: temp = self.active_input_field.text if key == 'backspace': if len(temp) > 0: self.active_input_field.text = temp[:-1] elif key == 'tab': new_index = self.input_field_list.index(self.active_input_field) + 1 try: self.active_input_field = self.input_field_list[new_index] except IndexError: self.active_input_field = self.input_field_list[0] elif key in ['1','2','3','4','5','6','7','8','9','0']: self.active_input_field.text = temp + key elif key in ['num_0', 'num_1', 'num_4', 'num_7', 'num_2', 'num_5', 'num_8', 'num_3', 'num_6', 'num_9']: self.active_input_field.text = temp + key[-1] elif key in ['comma', 'period', 'num_decimal']: self.active_input_field.text = temp + ',' for index, input_field in enumerate(self.input_field_list): if self.mouse.isPressedIn(input_field._frame, [0]): self.active_input_field = input_field if input_field is self.active_input_field: input_field._frame.fillColor = 'white' elif input_field._frame.fillColor == 'white': input_field._frame.fillColor = 'lightgrey' for input_field in self.input_field_list: if input_field.text == '': self.continue_button.clickable = False self.instructions_text.draw() self.continue_button.draw() for index, input_ in enumerate(self.input_field_list): input_.draw() self.input_prompt_list[index].draw() for item in self.extra_draw_list: item.draw() def cleanup(self): self.move_on_flag.clear() self.active_input_field = None self.window.flip() for item in self.input_field_list: self.answer_list.append(item.text) self.window.flip() self.window.flip() # # class PainfullyClearInstructions(Screen): # # # def __init__(self, disp): # super(PainfullyClearInstructions, self).__init__(disp) # # self.mypoints = [] # self.yourpoints = [] # for x, y in self.gen_points_coords(20, 4, 300, 300): # self.mypoints.append(Circle( # win=self.window, radius=10, # fillColor='white', lineColor=None, pos=(x,y) # )) # for x, y in self.gen_points_coords(20, 4, self.width-300-3*30, 300): # self.mypoints.append(Circle( # win=self.window, radius=10, # fillColor='black', lineColor=None, pos=(x,y) # )) # # def gen_points_coords(self, n, n_cols, col_1_x, row_1_y): # ys = [] # xs = [] # for i in range(n): # ys.append(floor((row_1_y + 30*i)/n_cols)) # xs.append(col_1_x + 30*(i % n_cols)) # return zip(xs, ys) # # def step1(self):
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
def __init__(self, disp, num_players, config_dict, gaze_pos_getter=None, width=None, height=None, margin=None, font_size=None, col_x_list=None): 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 is None: 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'] )) else: self.col_x_list = 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 = [] y_coords = [] for i in range(self.nrows): y = self.window.margin + i*row_spacing y_coords.append(y) 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: # self.nrows - 3 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.AOI_coords = [] for x in self.col_x_list: for y in y_coords: self.AOI_coords.append((x, y)) self.AOI_coords.remove((self.col_x_list[1], y_coords[0]))
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()
def __init__(self, disp, text, font_size=40, wait_time=0): super(InstructionsScreen, self).__init__(disp, wait_time=wait_time) self.instructions_text = TextStim( disp, pos=(0, 0), text=text, height=font_size, wrapWidth=self.w_cfg_2_pix(0.666) )
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()
class KeyboardInputScreen(Screen): """ A screen to allow users to enter data via the keyboard. """ def __init__(self, disp, text, input_prompt_list, correct_ans_list=None, extra_draw_list=None, wait_time=1): super(KeyboardInputScreen, self).__init__(disp, wait_time=wait_time) self.instructions_text = TextStim( disp, pos=(0, disp.vres*0.2), text=text, height=40, wrapWidth=1400 ) self.input_prompt_list = [] self.input_field_list = [] self.extra_draw_list = extra_draw_list if self.extra_draw_list is None: self.extra_draw_list = [] height_list = [] for i in range(len(input_prompt_list)): height_list.append( disp.vres*-0.2*i/(len(input_prompt_list)-1) ) for index, text in enumerate(input_prompt_list): self.input_prompt_list.append(TextStim( disp, pos=(disp.hres*-0.2, height_list[index]), text=text, height=40, wrapWidth=disp.hres*0.5 )) self.input_field_list.append(button.Button( disp, pos=(disp.hres*0.2, height_list[index]), font_size=30, width=disp.hres*0.15, height=40, text_color='black', text='' )) self.active_input_field = None self.answer_list = [] self.correct_ans_list = correct_ans_list def draw(self, debug_mode=False): key_list = getKeys() if self.active_input_field is not None: for key in key_list: temp = self.active_input_field.text if key == 'backspace': if len(temp) > 0: self.active_input_field.text = temp[:-1] elif key == 'tab': new_index = self.input_field_list.index(self.active_input_field) + 1 try: self.active_input_field = self.input_field_list[new_index] except IndexError: self.active_input_field = self.input_field_list[0] elif key in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']: self.active_input_field.text = temp + key elif key in ['num_0', 'num_1', 'num_4', 'num_7', 'num_2', 'num_5', 'num_8', 'num_3', 'num_6', 'num_9']: self.active_input_field.text = temp + key[-1] elif key in ['comma', 'period', 'num_decimal']: self.active_input_field.text = temp + ',' for index, input_field in enumerate(self.input_field_list): if self.mouse.isPressedIn(input_field.frame, [0]): self.active_input_field = input_field if input_field is self.active_input_field: input_field.color = 'white' elif input_field.color == 'white': input_field.color = 'lightgrey' for input_field in self.input_field_list: if input_field.text == '': self.continue_button.clickable = False self.instructions_text.draw() self.continue_button.draw() for index, input_ in enumerate(self.input_field_list): input_.draw() self.input_prompt_list[index].draw() for item in self.extra_draw_list: item.draw() def cleanup(self): self.move_on_flag.clear() self.active_input_field = None self.window.flip() for item in self.input_field_list: self.answer_list.append(item.text) self.window.flip() key_list = getKeys() if self.active_input_field is not None: for key in key_list: temp = self.active_input_field.text if key == 'backspace': if len(temp) > 0: self.active_input_field.text = temp[:-1] elif key == 'tab': new_index = self.input_field_list.index(self.active_input_field) + 1 try: self.active_input_field = self.input_field_list[new_index] except IndexError: self.active_input_field = self.input_field_list[0] elif key in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']: self.active_input_field.text = temp + key elif key in ['num_0', 'num_1', 'num_4', 'num_7', 'num_2', 'num_5', 'num_8', 'num_3', 'num_6', 'num_9']: self.active_input_field.text = temp + key[-1] elif key in ['comma', 'period', 'num_decimal']: self.active_input_field.text = temp + ',' for index, input_field in enumerate(self.input_field_list): if self.mouse.isPressedIn(input_field.frame, [0]): self.active_input_field = input_field if input_field is self.active_input_field: input_field.color = 'white' elif input_field.color == 'white': input_field.color = 'lightgrey' for input_field in self.input_field_list: if input_field.text == '': self.continue_button.clickable = False self.instructions_text.draw() self.continue_button.draw() for index, input_ in enumerate(self.input_field_list): input_.draw() self.input_prompt_list[index].draw() for item in self.extra_draw_list: item.draw()
class ProjectionsLinesAndCircles(object): """ Test jig for projection warping. Switch between warpings by pressing a key 'S'pherical, 'C'ylindrical, 'N'one, warp'F'ile. Click the mouse to set the eyepoint X, Y. Up / Down arrow or mousewheel to move eyepoint in and out. """ def __init__(self, win, warper): self.win = win self.warper = warper self.stimT = TextStim(self.win, text='Null warper', units = 'pix', pos=(0, -140), alignHoriz='center', height=20) self.bl = -win.size / 2.0 self.tl = (self.bl[0], -self.bl[1]) self.tr = win.size / 2.0 self.stims = [] self.degrees = 120 nLines = 12 for x in range(-nLines, nLines+1): t = GratingStim(win,tex=None,units='deg',size=[2,win.size[1]],texRes=128,color=foregroundColor, pos=[float(x) / nLines * self.degrees,0]) self.stims.append (t) for y in range (-nLines, nLines+1): t = GratingStim(win,tex=None,units='deg',size=[win.size[0],2],texRes=128,color=foregroundColor,pos=[0,float(y)/nLines * self.degrees]) self.stims.append (t) for c in range (1, nLines+1): t = Circle (win, radius=c * 10, edges=128, units='deg', lineWidth=4) self.stims.append (t) self.updateInfo() self.keys = key.KeyStateHandler() win.winHandle.push_handlers(self.keys) self.mouse = event.Mouse(win=self.win) def updateFrame(self): """ Updates frame with any item that is to be modulated per frame. """ for s in self.stims: s.draw() self.stimT.draw() def update_sweep(self): """ Update function for sweeps. Input is in domain units. """ self.updateFrame() self.check_keys() self._handleMouse() self.win.flip() def updateInfo(self): try: self.stimT.setText ("%s \n eyePoint: %.3f, %.3f \n eyeDistance: %.2f\n\nProjection: [s]pherical, [c]ylindrical, [n]one, warp[f]ile\nFlip: [h]orizontal, [v]ertical\nMouse: wheel = eye distance, click to set eyepoint\n[q]uit" % ( self.warper.warp, self.warper.eyepoint[0], self.warper.eyepoint[1], self.warper.dist_cm)) except: pass def check_keys(self): """Checks key input""" for keys in event.getKeys(timeStamped=True): k = keys[0] if k in ['escape', 'q']: self.win.close() sys.exit() elif k in ['space']: for c in range (1,2): t = Circle(self.win, radius=c) self.stims.append (t) #for c in range (1,2): # t = RadialStim(self.win) # self.stims.append(t) # handle projections elif k in ['s']: self.warper.changeProjection ('spherical', None, (0.5,0.5)) elif k in ['c']: self.warper.changeProjection ('cylindrical', None, (0.5,0.5)) elif k in ['n']: self.warper.changeProjection (None, None, (0.5,0.5)) elif k in ['f']: self.warper.changeProjection ('warpfile', r'..\data\sample.meshwarp.data', (0.5,0.5)) # flip horizontal and vertical elif k in ['h']: self.warper.changeProjection(self.warper.warp, self.warper.warpfile, flipHorizontal = not self.warper.flipHorizontal) elif k in ['v']: self.warper.changeProjection(self.warper.warp, self.warper.warpfile, flipVertical = not self.warper.flipVertical) # move eyepoint elif k in ['down']: if (self.warper.dist_cm > 1): self.warper.dist_cm -= 1 self.warper.changeProjection (self.warper.warp, None, self.warper.eyepoint) elif k in ['up']: if (self.warper.dist_cm < 200): self.warper.dist_cm += 1 self.warper.changeProjection (self.warper.warp, None, self.warper.eyepoint) elif k in ['right']: if (self.warper.eyepoint[0] < 0.9): self.warper.eyepoint = (self.warper.eyepoint[0] + 0.1, self.warper.eyepoint[1]) self.warper.changeProjection (self.warper.warp, None, self.warper.eyepoint) elif k in ['left']: if (self.warper.eyepoint[0] > 0.1): self.warper.eyepoint = (self.warper.eyepoint[0] - 0.1, self.warper.eyepoint[1]) self.warper.changeProjection (self.warper.warp, None, self.warper.eyepoint) self.updateInfo() def _handleMouse(self): x,y = self.mouse.getWheelRel() if y != 0: self.warper.dist_cm += y self.warper.dist_cm = max (1, min (200, self.warper.dist_cm)) self.warper.changeProjection (self.warper.warp, self.warper.warpfile, self.warper.eyepoint) self.updateInfo() pos = (self.mouse.getPos() + 1) / 2 leftDown = self.mouse.getPressed()[0] if leftDown: self.warper.changeProjection (self.warper.warp, self.warper.warpfile, pos) self.updateInfo()