def rad_checkboard(a1, a2): color_gr = [ round(choice(arange(-1, 1, 0.1)), 2), round(choice(arange(-1, 1, 0.1)), 2), round(choice(arange(-1, 1, 0.1)), 2) ] #color_gr=random.choice([red, green, black, blue]) #color_gr=black #color_gr=blue stim_vertical1 = visual.RadialStim(win, units="pix", pos=(0.0, 0.0), ori=90, size=(cm2pix(r_big) * 2, cm2pix(r_big) * 2), radialCycles=12, angularCycles=11, visibleWedge=(a1, a2), color=color_gr, colorSpace='rgb') stim_vertical2 = visual.RadialStim(win, units="pix", pos=(0.0, 0.0), ori=90, size=(cm2pix(r_small) * 2, cm2pix(r_small) * 2), radialCycles=12, angularCycles=11, visibleWedge=(a1, a2), color=grey, colorSpace='rgb') stim_vertical1.draw() stim_vertical2.draw()
def __init__(self, window, size, position, n_frame, log_time=False): """ Args: window (psychopy.visual.window): Psychopy window size (int): Size of the checkerboard stimulation position (tuple): Position of stimulation on the screen n_frame (int): Number of frames for the stim to flicker (frequency = monitor_refresh_rate/n_frame) log_time (bool): Whether to log toggle times """ self._window = window self._fr_rate = n_frame self._fr_counter = n_frame pattern = np.ones((4, 4)) pattern[::2, ::2] *= -1 pattern[1::2, 1::2] *= -1 self._stim1 = visual.RadialStim(win=self._window, tex=pattern, pos=position, size=size, radialCycles=1, texRes=256, opacity=1) self._stim2 = visual.RadialStim(win=self._window, tex=pattern * -1, pos=position, size=size, radialCycles=1, texRes=256, opacity=1) self._toggle_flag = False self.log_time = log_time self.toggle_times = []
def initialize_wedges(self): self.right_wedge = visual.RadialStim(win=self.mywin, tex='sqrXsqr', color=1, contrast=0.4, size=self.inner_wedge_size, visibleWedge=[45, 135], radialCycles=8, angularCycles=16, interpolate=False, autoLog=False) self.right_unvisible_wedge = visual.RadialStim( win=self.mywin, tex='sqrXsqr', mask='circle', color='grey', contrast=0, size=self.unvisible_inner_wedge_size, visibleWedge=[45, 135], radialCycles=8, angularCycles=16, interpolate=False, autoLog=False) self.left_wedge = visual.RadialStim(win=self.mywin, tex='sqrXsqr', color=1, contrast=0.4, size=self.inner_wedge_size, visibleWedge=[225, 315], radialCycles=8, angularCycles=16, interpolate=False, autoLog=False) self.left_unvisible_wedge = visual.RadialStim( win=self.mywin, tex='sqrXsqr', mask='circle', color='grey', contrast=0, size=self.unvisible_inner_wedge_size, visibleWedge=[225, 315], radialCycles=8, angularCycles=16, interpolate=False, autoLog=False)
def draw_cal_target(self, x, y): '''Draw the calibration/validation & drift-check target''' self.clear_cal_display() xVis = (x - self.w / 2) yVis = (self.h / 2 - y) if self.calTarget is 'default': self.calibTar.pos = (xVis, yVis) self.calibTar.draw() self.display.flip() else: if self.calTarget is 'rotatingCheckerboard': self.calibTar = visual.RadialStim(self.display, tex='sqrXsqr', mask='circle', radialCycles=2, angularCycles=6, size=1.0 / 20 * self.w) if self.calTarget is 'movie': self.calibTar = visual.MovieStim3(self.display, self.movieTargetFile, loop=True) self.calibTar.pos = (xVis, yVis) self.animatedTarget = True # turn on target animation
def test_radial(self): if self.win.winType == 'pygame': pytest.skip("RadialStim dodgy on pygame") win = self.win #using init wedge = visual.RadialStim(win, tex='sqrXsqr', color=1, size=2 * self.scaleFactor, visibleWedge=[0, 45], radialCycles=2, angularCycles=2, interpolate=False) wedge.draw() thresh = 10 utils.compareScreenshot('wedge1_%s.png' % (self.contextName), win, crit=thresh) win.flip() #AFTER compare screenshot #using .set() wedge.mask = 'gauss' wedge.size = 3 * self.scaleFactor wedge.angularCycles = 3 wedge.radialCycles = 3 wedge.ori = 180 wedge.contrast = 0.8 wedge.opacity = 0.8 wedge.radialPhase += 0.1 wedge.angularPhase = 0.1 wedge.draw() str(wedge) #check that str(xxx) is working utils.compareScreenshot('wedge2_%s.png' % (self.contextName), win, crit=10.0)
def test_radial(self): win = self.win #using init wedge = visual.RadialStim(win, tex='sqrXsqr', color=1, size=2* self.scaleFactor, visibleWedge=[0, 45], radialCycles=2, angularCycles=2, interpolate=False) wedge.draw() thresh = 15 # there are often a slight interpolation differences if win.winType != 'pygame': # pygame definitely gets radialstim wrong! utils.compareScreenshot('wedge1_%s.png' %(self.contextName), win, crit=thresh) win.flip()#AFTER compare screenshot #using .set() wedge.mask = 'gauss' wedge.size = 3 * self.scaleFactor wedge.angularCycles = 3 wedge.radialCycles = 3 wedge.ori = 180 wedge.contrast = 0.8 wedge.opacity = 0.8 wedge.radialPhase += 0.1 wedge.angularPhase = 0.1 wedge.draw() "{}".format(wedge) #check that str(xxx) is working if win.winType != 'pygame': # pygame gets this wrong: utils.compareScreenshot('wedge2_%s.png' %(self.contextName), win, crit=thresh) else: pytest.skip("Pygame fails to render RadialStim properly :-/")
def generate_radial_stimulus_list(win, positions_list, stimulus_size, radial_cycles=5, angular_cycles=12): stimulus_list = [] stimulus_mask_list = [] for stim_position in positions_list: wedge = visual.RadialStim(win, tex='sqrXsqr', color=-1, size=stimulus_size[0], pos=stim_position, units='pix', visibleWedge=[0, 360], radialCycles=5, angularCycles=12, interpolate=False, autoLog=False) stimulus_list.append(wedge) circle_target = visual.Circle(win, fillColor=[0.5, 0.5, 0.5], size=10, pos=stim_position, units='pix') stimulus_mask_list.append(circle_target) return stimulus_list, stimulus_mask_list
def test_radial(self): win = self.win #using init wedge = visual.RadialStim(win, tex='sqrXsqr', color=1, size=2 * self.scaleFactor, visibleWedge=[0, 45], radialCycles=2, angularCycles=2, interpolate=False) wedge.draw() utils.compareScreenshot('wedge1_%s.png' % (self.contextName), win, crit=10.0) win.flip() #AFTER compare screenshot #using .set() wedge.setOri(180) wedge.setContrast(0.8) wedge.setOpacity(0.8) wedge.setRadialPhase(0.1, operation='+') wedge.setAngularPhase(0.1) wedge.draw() utils.compareScreenshot('wedge2_%s.png' % (self.contextName), win, crit=10.0)
def __init__( self, window, size, pos, dutyCycle=0.125, nSegs=3, radialRate=0.05, #phase shift per frame (fraction of a cycle) changeProb=0.01, #percentage of frames on which dir changes ): self.segments = [] self.segWidth = dutyCycle * 360.0 / nSegs self.radialRate = radialRate self.changeProb = changeProb phase = 0 for n in range(nSegs): thisSeg = visual.RadialStim( window, pos=pos, angularRes=360, radialCycles=6, angularCycles=0, visibleWedge=[n * self.segWidth, (n + 1) * self.segWidth], size=size, texRes=64, mask=[0.5]) self.segments.append(thisSeg)
def create_blade(degree, ori): return visual.RadialStim(win=win, color=1, visibleWedge=[0, degree], radialCycles=0, angularCycles=90 // degree, ori=ori, size=1.5)
def __init__(self, rt_client, pport_addr): # FieldTrip buffer stuff self.rt_client = rt_client self.recent_epochs_obj = biosemi_fieldtrip_recent_epochs( self.rt_client, n_recent_event=10, event_types=[100, 200]) # where to send triggers self.pport_addr = pport_addr self.pport = windll.inpoutx64 # timers self.timer1 = core.Clock() self.timer2 = core.Clock() # stimulus display stuff self.mywin = visual.Window([800, 600], monitor="testMonitor", units="deg") # display window self.right_cb = visual.RadialStim(self.mywin, tex='sqrXsqr', color=1, size=5, visibleWedge=[0, 180], radialCycles=4, angularCycles=8, interpolate=False, autoLog=False) # right checkerboard self.left_cb = visual.RadialStim(self.mywin, tex='sqrXsqr', color=1, size=5, visibleWedge=[180, 360], radialCycles=4, angularCycles=8, interpolate=False, autoLog=False) # left checkerboard self.fixation = visual.PatchStim(self.mywin, color=-1, colorSpace='rgb', tex=None, mask='circle', size=0.2) # fixation # events self.ev_list = []
def blade_object(degree, ori): """each fan is made up of wedges or "blades" this function creates a single blade based on its size (degree) and orientation""" return visual.RadialStim(win=win, color=1, visibleWedge=[0, degree], radialCycles=0, angularCycles=90 // degree, ori=ori, size=1.5)
def __init__(self, win, side_len=8, inverted=False, size=700, **kwargs): self.win = win self.side_len = side_len self.inverted = inverted self.size = size self._array = self._get_array() self._stim = visual.RadialStim(win=self.win, tex=self._array, size=(self.size, self.size), radialCycles=1, **kwargs)
def make_radial(self): stimulus = visual.RadialStim( win=self.mywin, size=(self.stim_width, self.stim_width), angularCycles=12, radialCycles=4 ) # i think angular=12, radial=4 looks fairly good/balanced; increase to get more (smaller) squares numFrames = self.stim_dur * 60 #multiply stim_dur (seconds) by 60 to get number of frames we need to present the stimulus for (assuming 60 Hz monitor) marker = pdm.PhotodiodeMarker() for frame in range(numFrames): stimulus.draw() marker.draw_marker(self.mywin) self.mywin.flip()
def __init__(self): self.circle = visual.Circle(setup.mywin, units='pix', size = var.circle_fullSize, ori=0, pos=np.array([var.elX[0],var.elY[0]]), fillColor=var.gray2, fillColorSpace='rgb', opacity =1, interpolate=True) self.scale = visual.Line(setup.mywin, start=(0,0), end=(0,0)) self.clock = visual.RadialStim(setup.mywin,tex='sqrXsqr', mask='none', units='pix', pos=(0, 240), size=(148, 148), radialCycles=1, angularCycles=1, radialPhase=0, angularPhase=0, ori=0.0, texRes=64, angularRes=100, visibleWedge=(0, 0), rgb=None, color=(1.0, 1.0, 1.0), colorSpace='rgb', dkl=None, lms=None, contrast=0.0, opacity=1.0, depth=10, rgbPedestal=(1.0, 1.0, 1.0), interpolate=False, name=None, autoLog=None, maskParams=None) self.pressCircle = visual.Circle(setup.mywin, units='pix', size = 150, ori=0, pos=(0, 240), fillColor=None, fillColorSpace='rgb',opacity =1, interpolate=True) self.instruction = visual.TextStim(setup.mywin, units='pix', ori=0, name='Instructions',text=u'Block Name', font=u'Arial', pos=[0, 0], height=30, wrapWidth=None,color=u'black', colorSpace='rgb', opacity=1,depth=-12.0,alignVert='center',alignHoriz='center') self.survey_instr = visual.TextStim(setup.mywin, units='pix', ori=0, name='Instructions',text=u'Block Name', font=u'Arial', pos=[0, 0], height=20, wrapWidth=None,color=u'black', colorSpace='rgb', opacity=1,depth=-12.0,alignVert='center',alignHoriz='center')
def __init__(self, win=None, params=None, exp_info=None, txt_ins=None, stimulus_list=None): self.win = win self.params = params self.exp_info = exp_info self.txt_ins = txt_ins self.stimulus_list = stimulus_list if self.params["EEG"] : self.pport = PortParallel() else : self.pport = False self.oddball_trials_structure = [] for i in range(4) : self.oddball_trials_structure.append(get_oddball_list(self.params["N_deviant"])) self.stim_trials_list = get_oddball_stim(self.stimulus_list, self.win, params["Stim_list_folder"]) # Either create the target or load an image as the target if params[u"Oddball_target"] == "Cross" : self.target = visual.RadialStim(self.win, tex=None, color=(0, 0, 0), colorSpace='rgb255', pos=(0, 0), units='pix', size=(35, 35), mask=[0, 0, 0, 0, 0, 0, 1, 1], radialCycles=0, angularCycles=0, opacity=1, contrast=1.0, interpolate=False) self.fixation_cross_horizontal = visual.Line(win=self.win, units="pix", lineColor=[-1, -1, -1], lineWidth=4, start=(-15, 0), end=(+15, 0)) self.fixation_cross_vertical = visual.Line(win=self.win, units="pix", lineColor=[-1, -1, -1], lineWidth=4, start=(0, -15), end=(0, +15)) else : self.target = visual.ImageStim(self.win, image=params[u"Oddball_target"]) #Create data handler file_name = exp_info['Exp'] + "_Version" + exp_info['Version'] + "_" + exp_info["Name"] + "_Oddball" self.oddball_data = data.ExperimentHandler(name='Oddball', version=exp_info['Version'], extraInfo=exp_info, runtimeInfo=None, savePickle=False, saveWideText=True, dataFileName=params["Oddball_saving_path"]+file_name, autoLog=True)
def __init__( self, window, size, pos=[0, 0], dutyCycle=0.25, nRings=4, angularRate=1, #phase shift per frame (degs) changeProb=0.01, #percentage of frames on which dir changes ): self.rings = [] self.ringWidth = dutyCycle / nRings self.angularRate = angularRate self.changeProb = changeProb self.nRings = nRings self.pos = pos self.size = size self.radialPhase = 0 self._oneCycle = num.arange(0, 1.0, 1 / 128.0) self._oneCycle = num.where(self._oneCycle <= self.ringWidth, 1, 0) for n in range(nRings): thisStart = self.radialPhase + n * self.ringWidth theseIndices = num.arange(thisStart, thisStart + 1, 1 / 128.0) % 1.0 theseIndices = (theseIndices * 128).astype(num.uint8) thisMask = self._oneCycle[theseIndices] thisRing = visual.RadialStim( window, pos=self.pos, angularRes=360, radialCycles=0, angularCycles=16, size=self.size, texRes=64, mask=thisMask, ) self.rings.append(thisRing)
def MakeColorWheel(): global color_wheel, color_select, color_dir #Color wheel directions color_dir = visual.TextStim(win, height=0.7, wrapWidth=28, color='black', pos=(-1, 8), text=''' Use the mouse to select the color of the screen at the end of the interval. ''') #Create array of colors in hsv hsv = numpy.ones([256, 256, 3], dtype=float) hsv[:, :, 0] = numpy.linspace(0, 360, 256, endpoint=False) hsv[:, :, 1] = 1 hsv[:, :, 2] = 1 #Create color wheel color_wheel = visual.RadialStim(win, tex=misc.hsv2rgb(hsv), angularCycles=1, interpolate=True, texRes=360, size=(10, 10), pos=(-8, 0)) #Create color selection box color_select = visual.Rect(win, width=10, height=10, pos=(5, 0), lineColor='black', fillColor='white')
def test_radial(self): if self.win.winType == 'pygame': pytest.skip("RadialStim dodgy on pygame") win = self.win #using init wedge = visual.RadialStim(win, tex='sqrXsqr', color=1, size=2 * self.scaleFactor, visibleWedge=[0, 45], radialCycles=2, angularCycles=2, interpolate=False, autoLog=False) wedge.draw() thresh = 10 utils.compareScreenshot('wedge1_%s.png' % (self.contextName), win, crit=thresh) win.flip() #AFTER compare screenshot #using .set() wedge.setMask('gauss', log=False) wedge.setSize(3 * self.scaleFactor, log=False) wedge.setAngularCycles(3, log=False) wedge.setRadialCycles(3, log=False) wedge.setOri(180, log=False) wedge.setContrast(0.8, log=False) wedge.setOpacity(0.8, log=False) wedge.setRadialPhase(0.1, operation='+', log=False) wedge.setAngularPhase(0.1, log=False) wedge.draw() str(wedge) #check that str(xxx) is working utils.compareScreenshot('wedge2_%s.png' % (self.contextName), win, crit=10.0)
texture2 = ally * allx # only one quarter of the full sinusoid texture2 = numpy.where(texture2 > 0, 1, -1) #print('TEST0') # plot results #plt.imshow(texture) #plt.show() #plt.imshow(texture2) #plt.show() # make checkerboard stimuli check1 = visual.RadialStim(win, tex=texture, color=1, size=params['checkSize'], visibleWedge=[0, 360], radialCycles=1, angularCycles=1, interpolate=False) check2 = visual.RadialStim(win, tex=-texture, color=1, size=params['checkSize'], visibleWedge=[0, 360], radialCycles=1, angularCycles=1, interpolate=False) # make text messages message1 = visual.TextStim(win, pos=[0, 0],
win = visual.Window([screenSize[0], screenSize[0]], fullscr=False, allowGUI=False, monitor='testMonitor', screen=screen_to_show, units='pix') # STIMULI PARAMETERS #========================= stimA = visual.RadialStim(win, tex="sqrXsqr", ori=0, color=1, mask="none", units='deg', pos=(0, 0), texRes=256, angularRes=200, size=[100, 100], visibleWedge=[0, 360], radialCycles=35, angularCycles=12, name='stimA') stimAInt = visual.RadialStim(win, tex="sqrXsqr", ori=0, color=1, mask="none", units='deg', pos=(0, 0), texRes=256, angularRes=200,
def risk_choice(lot_col,lot_m,lot_p,lot_left,sure_m): event.clearEvents() print([lot_left,lot_p,lot_m,lot_col,sure_m]) if lot_col=='red': col_code=[1,0,0] elif lot_col=='green': col_code=[0,1,0] else: col_code=[0,0,1] if lot_left: lot_pos=-300 sure_pos=(300,0) else: lot_pos=300 sure_pos=(-300,0) tmp_div=np.divide(lot_p,100.00) shade=np.multiply(360.00,tmp_div)+1 print(shade) Outline= visual.RadialStim( win=win, name='OUTLINE', color=col_code,opacity=1, angularCycles = 0, radialCycles = 0, radialPhase = 0.5, colorSpace = 'rgb', ori= 45.0, pos=(lot_pos,0), size=(400,400)) Outline2= visual.RadialStim( win=win, name='OUTLINE_in', color=[0,0,0],opacity=1, angularCycles = 0, radialCycles = 0, radialPhase = 0.5, colorSpace = 'rgb', ori= 45.0, pos=(lot_pos,0), size=(380,380)) Outline.draw() Outline2.draw() Lot_a_win=visual.RadialStim(win=win,units="pix",name='Lot', color=col_code,opacity=1, angularCycles = 0, radialCycles = 0, radialPhase = 0.5, colorSpace = 'rgb', ori= -90.0,pos=(lot_pos,0), size=(300,300),visibleWedge=(0.0, shade)) Lot_a_lose= visual.RadialStim( win=win, name='rad2', color=col_code,opacity=0.5, angularCycles = 0, radialCycles = 0, radialPhase = 0.5, colorSpace = 'rgb', ori= 45.0, pos=(lot_pos,0), size=(300,300)) Lot_a_lose.draw() Lot_a_win.draw() SureMoney=visual.TextStim(win=win,text="$ %s"%(sure_m),pos=sure_pos,bold=True,units='pix') SureMoney.draw() Lot_per=visual.TextStim(win=win,text="%s %%"%(lot_p),pos=(lot_pos,-50),bold=True,units='pix') Lot_Money=visual.TextStim(win=win,text="$ %s"%(lot_m),pos=(lot_pos,50),bold=True,units='pix') Lot_per.draw() Lot_Money.draw() focus=visual.TextStim(win=win,text='+') focus.draw() win.flip() timer.reset() core.wait(0.3) keys=event.waitKeys(keyList=['f', 'j','escape'],maxWait=4.5) RT=timer.getTime() if not keys: keys='No_resp' RT=10 wait_sec=5-RT focus.draw() win.flip() core.wait(wait_sec) core.wait(0.3) return keys,RT
def Amb_choice(lot_left,lot_p,money,lot_col,Amb_level): event.clearEvents() print([lot_left,lot_p,money,lot_col,Amb_level]) if lot_col=='red': col_code=[1,0,0] elif lot_col=='green': col_code=[0,1,0] elif lot_col=='blue': col_code=[0,0,1] else: col_code=[1,1,0] if lot_left: lot_pos=-300 amb_pos=300 else: lot_pos=300 amb_pos=-300 tmp_div=np.divide(lot_p,100.00) shade=np.multiply(360.00,tmp_div)+1 tmp_div=np.divide(Amb_level,100.00) amb_shade=np.multiply(360.00,tmp_div)+1 print(shade) # The risky lottery has 3 parts. The Outline Win ammount. & Lose Amount R_Outline= visual.RadialStim( win=win, name='OUTLINE', color=[1,1,1],opacity=1, angularCycles = 0, radialCycles = 0, radialPhase = 0.5, colorSpace = 'rgb', ori= 45.0, pos=(lot_pos,0), size=(400,400)) R_Outline2= visual.RadialStim( win=win, name='OUTLINE_in', color=[0,0,0],opacity=1, angularCycles = 0, radialCycles = 0, radialPhase = 0.5, colorSpace = 'rgb', ori= 45.0, pos=(lot_pos,0), size=(380,380)) R_Outline.draw() R_Outline2.draw() Lot_a_win=visual.RadialStim(win=win,units="pix",name='Lot', color=[-1,-1,-1],opacity=1, angularCycles = 0, radialCycles = 0, radialPhase = 0.5, colorSpace = 'rgb', ori= -90.0,pos=(lot_pos,0), size=(300,300),visibleWedge=(0.0, shade)) Lot_a_lose= visual.RadialStim( win=win, name='rad2', color=[1,1,1],opacity=0.5, angularCycles = 0, radialCycles = 0, radialPhase = 0.5, colorSpace = 'rgb', ori= 45.0, pos=(lot_pos,0), size=(300,300)) Lot_a_lose.draw() Lot_a_win.draw() #The Ambiguous Lottery has 4 parts the Outline, Win shade, Lose Shade, & ambiguity shade if Amb_level==75: orn=45 else: orn=90 A_Outline= visual.RadialStim( win=win, name='OUTLINE', color=col_code,opacity=1, angularCycles = 0, radialCycles = 0, radialPhase = 0.5, colorSpace = 'rgb', ori= 0, pos=(amb_pos,0), size=(400,400)) A_Outline2= visual.RadialStim( win=win, name='OUTLINE_in', color=[0,0,0],opacity=1, angularCycles = 0, radialCycles = 0, radialPhase = 0.5, colorSpace = 'rgb', ori= 0, pos=(amb_pos,0), size=(380,380)) A_Outline.draw() A_Outline2.draw() A_win=visual.RadialStim(win=win,units="pix",name='Lot', color=col_code,opacity=1, angularCycles = 0, radialCycles = 0, radialPhase = 0.5, colorSpace = 'rgb', ori= 0,pos=(amb_pos,0), size=(300,300),visibleWedge=(0.0,180)) A_lose = visual.RadialStim( win=win, name='rad2', color=col_code,opacity=0.3, angularCycles = 0, radialCycles = 0, radialPhase = 0.5, colorSpace = 'rgb', ori= 0, pos=(amb_pos,0), size=(300,300)) cover= visual.RadialStim( win=win, name='rad2', color=[0.2,0.2,0.2],opacity=1, angularCycles = 0, radialCycles = 0, radialPhase = 0.5, colorSpace = 'rgb', ori=orn, pos=(amb_pos,0), size=(300,300),visibleWedge=(0.0,amb_shade)) A_lose.draw() A_win.draw() cover.draw() #AmbMoney=visual.TextStim(win=win,text="$ %s"%(money),pos=(amb_pos,50),bold=True) #AmbMoney.draw() am_per_text="%s %% - %s %%"%(50-np.divide(Amb_level,2),50+np.divide(Amb_level,2)) AmbPer=visual.TextStim(win=win,text=am_per_text,pos=(amb_pos,-50),bold=True) AmbPer.draw() Lot_per=visual.TextStim(win=win,text="%s %%"%(lot_p),pos=(lot_pos,-50),bold=True) Lot_per.draw() focus=visual.TextStim(win=win,text='+') focus.draw() Lot_Money=visual.TextStim(win=win,text="$ %s"%(money),pos=(0,50),bold=True) Lot_Money.draw() win.flip() timer.reset() maxwait=4 core.wait(0.3) keys=event.waitKeys(keyList=['f', 'j','escape'],maxWait=maxwait) RT=timer.getTime() print(RT) if lot_col==lot_color[0]: dist='wide' elif lot_col==lot_color[1]: dist='narrow' elif lot_col==lot_color[2]: dist='skew' elif lot_col=='yellow': dist='True_unkown' if not keys: keys='No_resp' RT=maxwait wait_sec=4.5-RT focus.draw() win.flip() core.wait(wait_sec) core.wait(0.3) return keys,RT,dist
# Create a window to draw in win = visual.Window((600, 600), allowGUI=False, monitor='testMonitor', units='deg', blendMode='avg', allowStencil=True) nTrials = 10 # Initialize some stimuli # create the mask we will draw the stimulus through - can only use one so draw one annulus and we will rotate it mask = visual.RadialStim( win, tex='none', color=1, size=1, visibleWedge=[2, 178], radialCycles=4, angularCycles=8, interpolate=False, autoLog=False) # this stim changes too much for autologging to be useful # gratings for plaid stimulus grating1 = visual.GratingStim(win, tex="sin", mask="circle", texRes=512, color='white', size=10, sf=2, ori=45, depth=0.5, opacity=0.5,
#!/usr/bin/env python2 #rotate flashing wedge from psychopy import visual, event, core globalClock = core.Clock() win = visual.Window([800, 800]) #make two wedges (in opposite contrast) and alternate them for flashing wedge1 = visual.RadialStim( win, tex='sqrXsqr', color=1, size=1, visibleWedge=[0, 45], radialCycles=4, angularCycles=8, interpolate=False, autoLog=False) #this stim changes too much for autologging to be useful wedge2 = visual.RadialStim( win, tex='sqrXsqr', color=-1, size=1, visibleWedge=[0, 45], radialCycles=4, angularCycles=8, interpolate=False, autoLog=False) #this stim changes too much for autologging to be useful t = 0 rotationRate = 0.01 #revs per sec flashPeriod = 0.1 #seconds for one B-W cycle (ie 1/Hz) while t < 5: #for 5 secs
def constructThickThinWedgeRingsTargetAndCue( myWin, initialAngle, radius, radialMask, radialMaskTarget, cueRadialMask, visibleWedge, numObjects, patchAngleThick, patchAngleThin, bgColor, thickWedgeColor, thinWedgeColor, targetAngleOffset, targetRadialOffset, gratingTexPix, cueColor, objToCue, ppLog): #Construct a grating formed of the colors in order of stimColorIdxsOrder #Also construct a similar cueRing grating with same colors, but one blob potentially highlighted. #cueRing Has different spacing than ringRadial, not sure why, I think because calculations tend to be off as it's #always one cycle. #radialMask doesn't seem to eliminate very-central part, bizarre antialiasGrating = False #Don't set this to true because in present context, it's like imposing a radial Gaussian ramp on each object autoLogging = False numCycles = numObjects segmentAngle = 360. / numCycles #create texture for red-green-blue-red-green-blue etc. radial grating #2-D texture which will draw the ring of objects via openGL texture on grating ringTex = np.zeros([ gratingTexPix, gratingTexPix, 3 ]) + bgColor[0] #start with all channels in all locs = bgColor cueTex = np.zeros([ gratingTexPix, gratingTexPix, 3 ]) + bgColor[0] #start with all channels in all locs = bgColor decoyTex = np.zeros([ gratingTexPix, gratingTexPix, 3 ]) + bgColor[0] #start with all channels in all locs = bgColor oneCycleAngle = 360. / numCycles def patchSizeForTexture(segmentAngle, patchAngle, oneCycleAngle, gratingTexPix): segmentSizeTexture = segmentAngle / oneCycleAngle * gratingTexPix #I call it segment because includes spaces between objects, that I'll write over subsequently if patchAngle > segmentAngle: msg = 'Error: patchAngle requested (' + str( patchAngle) + ') bigger than maximum possible (' + str( segmentAngle) + ') numCycles=' + str(numCycles) print(msg) ppLog.error(msg) patchSizeTexture = patchAngle * 1.0 / oneCycleAngle * gratingTexPix patchSizeTexture = round( patchSizeTexture) #best is odd number, even space on either size patchFlankSize = int((segmentSizeTexture - patchSizeTexture) / 2.) #this area will be drawn in bgColor patchAngleActual = patchSizeTexture * 1.0 / gratingTexPix * oneCycleAngle if abs(patchAngleActual - patchAngle) > .03: msg = 'Desired patchAngle = ' + str( patchAngle) + ' but closest can get with ' + str( gratingTexPix) + ' gratingTexPix is ' + str( patchAngleActual) ppLog.warn(msg) return segmentSizeTexture, patchSizeTexture, patchFlankSize #thick wedges. Create texture for visual.radialStim segmentSizeTexture, patchSizeTexture, patchFlankSize = patchSizeForTexture( segmentAngle, patchAngleThick, oneCycleAngle, gratingTexPix) start = 0 #identify starting texture position for this segment end = int(round(start + segmentSizeTexture) ) #don't round until after do addition, otherwise can fall short angRes = 200 #100 is default. I have not seen an artifact at present when set to 100, two things drawn don't overlap exactly #First draw the entire segment in patchColr, then erase sides (flankers) leaving only the patchAngle ringTex[:, start:end, :] = thickWedgeColor[:] #spaces in between objects are termed the flanks, should be bgColor, ringTex[:, start:start + patchFlankSize, :] = bgColor[:] #one flank ringTex[:, end - 1 - patchFlankSize:end, :] = bgColor[:] #other flank #thin wedges. Create texture for visual.radialStim segmentSizeTexture, thinWedgeSizeTexture, patchFlankSizeThinWedge = patchSizeForTexture( segmentAngle, patchAngleThin, oneCycleAngle, gratingTexPix) #Instead of drawing the red and undisplaced blue with the same call to radialStim, #We will draw the red with one call to radialStim, then the thinner blue sliver on top, using radialMask so it's only the sliver and leaves the #remainder of the red showing. #First draw the thick red contexts thickWedges ringRadialThickWedges = visual.RadialStim( myWin, tex=ringTex, color=[1, 1, 1], size= radius, #ringTex is the actual colored pattern. radial grating used to make it an annulus visibleWedge=visibleWedge, ori=initialAngle, #essentially the phase of the grating mask= radialMask, # this is a 1-D mask masking the centre, to create an annulus radialCycles=0, angularCycles=numObjects, angularRes=angRes, interpolate=antialiasGrating, autoLog=autoLogging) #thinWedge, the usually-blue target #First draw the entire segment in thinWedgeColor, then erase sides (flankers) leaving only the patchAngle (wedge angle) thinRingTex = np.zeros([ gratingTexPix, gratingTexPix, 3 ]) + bgColor[0] #start with all channels in all locs = bgColor thinRingTex[:, start:end, :] = thinWedgeColor[:] #spaces in between objects are termed the flanks, should be bgColor, thinRingTex[:, start:start + patchFlankSize, :] = bgColor[:] #one flank thinRingTex[:, end - 1 - patchFlankSize:end, :] = bgColor[:] #other flank ringRadialThinWedges = visual.RadialStim( myWin, tex=thinRingTex, color=[1, 1, 1], size= radius, #ringTex is the actual colored pattern. radial grating used to make it an annulus visibleWedge=visibleWedge, ori=initialAngle, #essentially the phase of the grating mask= radialMaskTarget, # this is a 1-D mask masking the centre, to create an annulus radialCycles=0, angularCycles=numObjects, angularRes=angRes, interpolate=antialiasGrating, autoLog=autoLogging) #Draw target (task is to judge offset of thin wedge relative to thick wedge, or brightness of target) #So, overdraw a single segment of the grating by using visibleWedge #angularPhase = #I need to not show the part of the thick wedge that will be displaced, while showing enough of thick wedge to overdraw previous location of thin wedge targetCorrectedForRingReversal = objToCue #numObjects-1 - objToCue #grating seems to be laid out in opposite direction than blobs, this fixes postCueNumBlobsAway so positive is in direction of motion kludgeWiden = 5 visibleAngleStart = targetCorrectedForRingReversal * segmentAngle + ( segmentAngle - patchAngleThick) / 2 - kludgeWiden visibleAngleEnd = (visibleAngleStart + kludgeWiden) + patchAngleThick + kludgeWiden #print('targetCorrectedForRingReversal = ',targetCorrectedForRingReversal,'targetRing initialAngle=', initialAngle, ' visibleAngleStart=',visibleAngleStart,' visibleAngleEnd=',visibleAngleEnd) if targetAngleOffset >= 0: visibleAngleEnd -= targetAngleOffset #don't show the part of the thick wedge that would be displaced else: #shifted the other way, towards the start, so spillover on that side needs to be avoided by not drawing it visibleAngleStart -= targetAngleOffset #DRAW THE TARGET RING, like the above ringRadial except displaced #Below call is identical to ringRadial except ori #set visibleWedge so it only highlights a single thick wedge targetRadial = visual.RadialStim( myWin, tex=thinRingTex, color=[1, 1, 1], size=radius + targetRadialOffset, #ringTex is the actual colored pattern. radial grating used to make it an annulus visibleWedge=[visibleAngleStart, visibleAngleEnd], ori=initialAngle + targetAngleOffset, #Always zero in the new version where the task is to judge the radial offset of the blue thin wedge mask= radialMaskTarget, # this is a 1-D mask masking the centre, to create an annulus radialCycles=0, angularCycles=numObjects, angularRes=angRes, interpolate=antialiasGrating, autoLog=autoLogging) #MAKE A COPY of the thick red ring to draw over undisplaced blue ringRadialThickWedgesCopy = visual.RadialStim( myWin, tex=ringTex, color=[1, 1, 1], size= radius, #ringTex is the actual colored pattern. radial grating used to make it an annulus visibleWedge=(visibleAngleStart, visibleAngleEnd), ori=initialAngle, mask= radialMask, # this is a 1-D mask masking the centre, to create an annulus radialCycles=0, angularCycles=numObjects, angularRes=angRes, interpolate=antialiasGrating, autoLog=autoLogging) #Draw lines (alternative target) lines = [] #calculate estimated eccentricity that grating target would be at, if were using grating targets #Find the center of the ones in radialMaskTarget, multiply by grating radius oneIndices = np.where(radialMaskTarget == 1)[0] oneIndexMean = np.mean(oneIndices) proportnOfRadius = oneIndexMean / len(radialMaskTarget) proportnOfRadius += 0.5 * 1 / len( radialMaskTarget ) #Because grating mask doesn't work with centering, rather it's the beginning or something so need to add to get to center of wedge eccentricity = proportnOfRadius * radius eccentricity = eccentricity / 1.97 #Don't know why need to divide by almost 2 #print("oneIndexMean = ", oneIndexMean, "proportnOfRadius = ", proportnOfRadius, "eccentricity = ", eccentricity) #Calculate appropriate line width in deg wedgeThicknessFraction = len( np.where(radialMask)[0]) * 1.0 / len(radialMask) wedgeThickness = wedgeThicknessFraction * radius / 2 targeti = targetCorrectedForRingReversal % numObjects # (targetCorrectedForRingReversal-1) % numObjects #dont know why have to subtract 1. Then have to mod numObjects so negative number gets turned into positive targetFillColors = np.array([[.9, .9, .9], [-.8, -.8, -.8]]) # [-.3,-.3,-.3] if sys.version_info[0] == 3: #python3 rangeOverObjects = range(0, numObjects) else: #python2 rangeOverObjects = xrange(0, numObjects) for i in rangeOverObjects: lineHeight = wedgeThickness * 1.0 # *1.0 lineWidth = lineHeight / 4 #divided by 10 makes it really small alex size, with div 4 being same as E2 angleDeg = initialAngle angleDeg += ( visibleAngleStart + visibleAngleEnd ) / 2 #because when gratings are drawn, there's this additional offset for which bit of the grating is visible angleDeg += i / numObjects * 360 tangentialOrientation = i / numObjects * 360 if __name__ != "__main__": #not self-test halfAngle = 360 / numObjects / 2 #For some reason target is offset by half the distance between two objects, even though that doesn't happen in helpersAOH self-test tangentialOrientation += halfAngle x = cos(gratingAngleToEuclidean(angleDeg) * pi / 180) * eccentricity y = sin(gratingAngleToEuclidean(angleDeg) * pi / 180) * eccentricity lineColor = targetFillColors[0] if i == targeti: #print("line targeti=", targeti, " angleDeg=",angleDeg, "Euclidean angle=",gratingAngleToEuclidean(angleDeg) ) orientation = tangentialOrientation if targetRadialOffset < 0: #it's always one of two values, a negative one and a positive one #orientation = tangentialOrientation + 90 lineColor = targetFillColors[1] #opposite color else: #orientation = tangentialOrientation + random.randint(0,1)*90 lineColor = targetFillColors[random.randint(0, 1)] #if orientation==tangentialOrientation: #make bigger because harder to see # lineHeight *= 1.4 #for tangential, make longer #else: lineHeight *=.8 #print("Drawing line ",i," at x=",x, " y=", y, "targetCorrectedForRingReversal=", targetCorrectedForRingReversal ) #thisLine = visual.Rect(myWin, width=lineWidth, height=lineHeight, pos=(x,y), ori=orientation, fillColor=lineColor, lineColor=None, autoLog=autoLogging) thisLine = visual.Circle(myWin, radius=lineWidth, pos=(x, y), fillColor=lineColor, lineColor=None, autoLog=autoLogging) lines.append(thisLine) #CREATING CUE TEXTURE #Both inner and outer cue arcs can be drawn in one go via a radial mask #use visibleWedge so it only highlights a single thick wedge start = 0 #identify starting texture position for this segment #start:end is meant to be entire segment, but the flanks, patchFlank, are drawn in bgColor #But remember this is a texture so maybe the first patchFlankSize portion is meant to be bg start = patchFlankSize end = start + segmentSizeTexture - 2 * patchFlankSize start = int(round(start)) end = int(round(end)) decoyTex[:, start:end, :] = cueColor[:] #Because I'm only showing a tiny sliver via visibleAngle, can color the whole thing cueTex[:, :, :] = cueColor[:] # start = 0 #identify starting texture position for this segment # start = int( round( start+patchFlankSize ) ) # end = int( round(start + segmentSizeTexture - patchFlankSize) )#don't round until after do addition, otherwise can fall short # cueTex[:, start:end, :] = cueColor[:] # cueTex[:, :, :] = cueColor[:] #draw cue visibleAngleStart = 0 visibleAngleEnd = 360 if objToCue >= 0: objToCueCorrectdForRingReversal = objToCue #numObjects-1 - objToCue #grating seems to be laid out in opposite direction than blobs, this fixes postCueNumBlobsAway so positive is in direction of motion kludgeCueThickenToMatchDecoy = 3 visibleAngleStart = objToCueCorrectdForRingReversal * segmentAngle + ( segmentAngle - patchAngleThick) / 2 - kludgeCueThickenToMatchDecoy visibleAngleEnd = visibleAngleStart + patchAngleThick + kludgeCueThickenToMatchDecoy + 2 #print('objToCueCorrectdForRingReversal = ',objToCueCorrectdForRingReversal,' visibleAngleStart=',visibleAngleStart,' visibleAngleEnd=',visibleAngleEnd) #decoyRing is optional ring to show a precue around all object positions, to eventually be replaced by a ring around only the target object decoyRing = visual.RadialStim( myWin, tex=decoyTex, color=[1, 1, 1], size=radius, #cueTexInner is white. Only one sector of it shown by mask ori=initialAngle, mask=cueRadialMask, radialCycles=0, angularCycles=numObjects, angularRes=angRes, interpolate=antialiasGrating, autoLog=autoLogging) cueRing = visual.RadialStim( myWin, tex=cueTex, color=[1, 1, 1], size=radius, #cueTexInner is white. Only one sector of it shown by mask visibleWedge=[visibleAngleStart, visibleAngleEnd], ori=initialAngle, mask=cueRadialMask, radialCycles=0, angularCycles= 1, #only one cycle because no pattern actually repeats- trying to highlight only one sector angularRes=angRes, interpolate=antialiasGrating, autoLog=autoLogging) return ringRadialThickWedges, ringRadialThickWedgesCopy, ringRadialThinWedges, targetRadial, cueRing, lines, decoyRing
def constructRingsAsGratings(myWin, numRings, radii, ringRadialMaskEachRing, numObjects, patchAngle, colors, stimColorIdxsOrder, gratingTexPix, blobToCueEachRing, ppLog): #Originally to construct a grating formed of the colors in order of stimColorIdxsOrder antialiasGrating = True autoLogging = False texEachRing = list( ) #texture which will draw the ring of objects via openGL texture on grating cueTexEachRing = list( ) #making a separate grating for the cue, wherein everything background color except the location of the cue ringsRadial = list() #after making the rings of object, put them in this list cueRings = list() #after making grating for each cue, put it in this cue stimColorIdxsOrder = stimColorIdxsOrder[:: -1] #reverse order of indices, because grating texture is rendered in reverse order than is blobs version radialMaskEachRing = [[ 0, 0, 0, 1, 1, ], [ 0, 0, 0, 0, 0, 0, 1, 1, ], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, ]] numUniquePatches = len(max(stimColorIdxsOrder, key=len)) numCycles = (1.0 * numObjects) / numUniquePatches angleSegment = 360. / (numUniquePatches * numCycles) if gratingTexPix % numUniquePatches > 0: #gratingTexPix contains numUniquePatches. numCycles will control how many total objects there are around circle ppLog.warn('Warning: could not exactly render a ' + str(numUniquePatches) + '-segment pattern radially, will be off by ' + str((gratingTexPix % numUniquePatches) * 1.0 / gratingTexPix)) if numObjects % numUniquePatches > 0: msg = 'Warning: numUniquePatches (' + str( numUniquePatches) + ') not go evenly into numObjects' ppLog.warn(msg) #create texture for red-green-blue-red-green-blue etc. radial grating for i in range(numRings): #myTex.append(np.zeros([gratingTexPix,gratingTexPix,3])+[1,-1,1]) texEachRing.append( np.zeros([gratingTexPix, gratingTexPix, 3]) + bgColor[0]) #start with all channels in all locs = bgColor cueTexEachRing.append( np.ones([gratingTexPix, gratingTexPix, 3]) * bgColor[0]) if patchAngle > angleSegment: msg = 'Error: patchAngle requested (' + str( patchAngle) + ') bigger than maximum possible (' + str( angleSegment) + ') numUniquePatches=' + str( numUniquePatches) + ' numCycles=' + str(numCycles) print(msg) ppLog.error(msg) oneCycleAngle = 360. / numCycles segmentSizeTexture = angleSegment / oneCycleAngle * gratingTexPix #I call it segment because includes spaces in between, that I'll write over subsequently patchSizeTexture = patchAngle / oneCycleAngle * gratingTexPix patchSizeTexture = round( patchSizeTexture) #best is odd number, even space on either size patchFlankSize = (segmentSizeTexture - patchSizeTexture) / 2. patchAngleActual = patchSizeTexture / gratingTexPix * oneCycleAngle if abs(patchAngleActual - patchAngle) > .03: #.01 msg = 'Desired patchAngle = ' + str( patchAngle) + ' but closest can get with ' + str( gratingTexPix) + ' gratingTexPix is ' + str(patchAngleActual) ppLog.warn(msg) for colrI in range( numUniquePatches): #for that portion of texture, set color start = colrI * segmentSizeTexture end = start + segmentSizeTexture start = round( start ) #don't round until after do addition, otherwise can fall short end = round(end) ringColr = list() for i in range(numRings): ringColr.append(colors[stimColorIdxsOrder[i][colrI]]) for colorChannel in range(3): for i in range(numRings): texEachRing[i][:, start:end, colorChannel] = ringColr[i][colorChannel] for cycle in range(int(round(numCycles))): base = cycle * gratingTexPix / numCycles for i in range(numRings): cueTexEachRing[i][:, base + start / numCycles:base + end / numCycles, colorChannel] = ringColr[1][colorChannel] #draw bgColor area (emptySizeEitherSideOfPatch) by overwriting first and last entries of segment for i in range(numRings): texEachRing[i][:, start:start + patchFlankSize, :] = bgColor[0] #one flank texEachRing[i][:, end - 1 - patchFlankSize:end, :] = bgColor[0] #other flank for cycle in range(int(round(numCycles))): base = cycle * gratingTexPix / numCycles for i in range(numRings): cueTexEachRing[i][:, base + start / numCycles:base + (start + patchFlankSize) / numCycles, :] = bgColor[0] cueTexEachRing[i][:, base + (end - 1 - patchFlankSize) / numCycles:base + end / numCycles, :] = bgColor[0] #color the segment to be cued white. First, figure out cue segment len segmentLen = gratingTexPix / numCycles * 1 / numUniquePatches WhiteCueSizeAdj = 0 # adust the white cue marker wingAdd 20110923 if numObjects == 3: WhiteCueSizeAdj = 110 elif numObjects == 6: WhiteCueSizeAdj = 25 elif numObjects == 12: WhiteCueSizeAdj = -15 elif numObjects == 2: WhiteCueSizeAdj = 200 for i in range(numRings): #color cue position white if blobToCueEachRing[i] >= 0: #-999 means dont cue anything blobToCueCorrectForRingReversal = numObjects - 1 - blobToCueEachRing[ i] #grating seems to be laid out in opposite direction than blobs, this fixes postCueNumBlobsAway so positive is in direction of motion if blobToCueCorrectForRingReversal == 0 and numObjects == 12: WhiteCueSizeAdj = 0 cueStartEntry = blobToCueCorrectForRingReversal * segmentLen + WhiteCueSizeAdj cueEndEntry = cueStartEntry + segmentLen - 2 * WhiteCueSizeAdj cueTexEachRing[i][:, cueStartEntry:cueEndEntry, :] = -1 * bgColor[ 0] #-1*bgColor is that what makes it white? blackGrains = round( .25 * (cueEndEntry - cueStartEntry) ) #number of "pixels" of texture at either end of cue sector to make black. Need to update this to reflect patchAngle cueTexEachRing[i][:, cueStartEntry:cueStartEntry + blackGrains, :] = bgColor[0] #this one doesn't seem to do anything? cueTexEachRing[i][:, cueEndEntry - 1 - blackGrains:cueEndEntry, :] = bgColor[0] angRes = 100 #100 is default. I have not seen any effect. This is currently not printed to log file! for i in range(numRings): ringsRadial.append( visual.RadialStim( myWin, tex=texEachRing[i], color=[1, 1, 1], size=radii[ i], #myTexInner is the actual colored pattern. radial grating used to make it an annulus mask=ringRadialMaskEachRing[ i], # this is a 1-D mask dictating the behaviour from the centre of the stimulus to the surround. radialCycles=0, angularCycles=numObjects * 1.0 / numUniquePatches, angularRes=angRes, interpolate=antialiasGrating, autoLog=autoLogging)) #the mask is radial and indicates that should show only .3-.4 as one moves radially, creating an annulus #end preparation of colored rings #draw cueing grating for tracking task. Have entire grating be empty except for one white sector cueRings.append( visual.RadialStim( myWin, tex=cueTexEachRing[i], color=[1, 1, 1], size=radii[ i], #cueTexInner is white. Only one sector of it shown by mask mask=radialMaskEachRing[i], radialCycles=0, angularCycles= 1, #only one cycle because no pattern actually repeats- trying to highlight only one sector angularRes=angRes, interpolate=antialiasGrating, autoLog=autoLogging) ) #depth doesn't seem to work, just always makes it invisible? currentlyCuedBlobEachRing = blobToCueEachRing #this will mean that don't have to redraw return ringsRadial, cueRings, currentlyCuedBlobEachRing
useFBO=True, ) # store frame rate of monitor if we can measure it successfully expInfo['frameRate'] = win.getActualFrameRate() if expInfo['frameRate'] != None: frameDur = 1.0 / round(expInfo['frameRate']) else: frameDur = 1.0 / 60.0 # couldn't get a reliable measure so guess #make two wedges (in opposite contrast) and alternate them for flashing wedgeRonC1 = visual.RadialStim( win, tex='sqrXsqr', color=1, size=2, visibleWedge=[15, 165], radialCycles=6, angularCycles=10, interpolate=False, ori=0, opacity=1, autoLog=False) #this stim changes too much for autologging to be useful wedgeRoffC1 = visual.RadialStim( win, tex='sqrXsqr', color=-1, size=2, visibleWedge=[15, 165], radialCycles=6, angularCycles=10, interpolate=False, ori=0,
# Instantiating stimulation client # Port number must match port number used to instantiate # StimServer. Any port number above 1000 should be fine # because they do not require root permission. stim_client = StimClient('localhost', port=4218) # create a window mywin = visual.Window([800, 600], monitor="testMonitor", units="deg") # create the stimuli # right checkerboard stimuli right_cb = visual.RadialStim(mywin, tex='sqrXsqr', color=1, size=5, visibleWedge=[0, 180], radialCycles=4, angularCycles=8, interpolate=False, autoLog=False) # left checkerboard stimuli left_cb = visual.RadialStim(mywin, tex='sqrXsqr', color=1, size=5, visibleWedge=[180, 360], radialCycles=4, angularCycles=8, interpolate=False, autoLog=False) # fixation dot fixation = visual.PatchStim(mywin, color=-1, colorSpace='rgb', tex=None, mask='circle', size=0.2) # the most accurate method is using frame refresh periods # however, since the actual refresh rate is not known # we use the Clock
from psychopy import visual, core, event import time mywin = visual.Window([1200,1200],monitor="testMonitor", units="deg", winType = 'glfw',) wedge = visual.RadialStim(win = mywin, size =(30, 30), radialCycles = 0, angularCycles = 4) counter_win = visual.Window([300,300],monitor="testMonitor", units="cm", winType = 'glfw',) counter = visual.TextStim(counter_win, text = str(0), height = 8) counter.autoDraw = True start_time = time.time() direction = 1 dir_time = 2 dir_change_number = 0 while True: time.sleep(0.0001) if time.time() - (start_time + ((dir_change_number + 1) * dir_time)) > 0: dir_change_number += 1 direction *= -1 counter.setText(str(dir_change_number)) wedge.angularPhase += direction *.005 wedge.draw()