def stimulus_random(random_index): dotsRandomstop = visual.DotStim(win=myWin, nDots=50, units='pixels', fieldSize=200, fieldShape='circle', coherence=1, dotSize=10, dir=random_index, speed=0, dotLife=-1) dotsRandom = visual.DotStim(win=myWin, nDots=50, units='pixels', fieldSize=200, fieldShape='circle', coherence=1, dotSize=10, dir=random_index, speed=2, dotLife=-1) dotsRandomstop.draw() myWin.flip() core.wait(2) for i in range(300): dotsRandom.draw() myWin.flip()
def runLotsOfDots(self, win, fieldShape, starting=100): """DotStim stress test: draw increasingly many dots until drop frames""" win.setRecordFrameIntervals(True) # define dots to be drawn: dots = range(starting // 100, 12) dotPatch = [ visual.DotStim(win, fieldShape=fieldShape, color=(1.0, 1.0, 1.0), dotSize=5, nDots=i * 100) for i in dots ] secs = 1 # how long to draw them for, at least 1s # baseline fps: for i in xrange(5): win.flip() # wake things up win.fps() # reset for i in xrange(60): win.flip() baseline = win.fps() dotsList = [] i = 0 win.flip() win.fps() # reset trialClock = core.Clock() bestDots = 0 while True: dotPatch[i].draw() win.flip() if trialClock.getTime() >= secs: fps = win.fps() frames_dropped = round(baseline - fps) if not frames_dropped: bestDots = dotPatch[i].nDots dotsList.append(('dots_' + str(dotPatch[i].nDots), str(frames_dropped), '')) i += 1 if i >= len(dotPatch): dotPatch.append( visual.DotStim(win, color=(1.0, 1.0, 1.0), fieldShape=fieldShape, nDots=dotPatch[i - 1].nDots + 100)) if fps < baseline * 0.6: dotsList.append( ('best_dots_' + fieldShape, str(bestDots), '')) break trialClock.reset() win.fps() # reset win.setRecordFrameIntervals(False) win.flip() return dotsList
def new_trial(self, **kwargs): # Trial info self.trial = { 'ground_truth': self.rng.choice(self.choices), 'coh': self.rng.choice(self.cohs), } self.trial.update(kwargs) coh = self.trial['coh'] ground_truth = self.trial['ground_truth'] stim_theta = self.theta[ground_truth] * (180 / np.pi) # Periods self.add_period(['fixation', 'stimulus', 'decision'], after=0, last_period=True) # Observations stim = visual.DotStim(self.win, nDots=30, dotSize=1, speed=0.05, dotLife=10, signalDots='same', fieldShape='circle', coherence=(coh / 100), dir=stim_theta * (180 / np.pi)) self.add_ob(stim, 'stimulus') # Ground truth self.set_groundtruth(self.act_dict['choice'][ground_truth], 'decision')
def test_movement(self): # Window needs to be black so that adding 2 screens doesn't make a white screen self.win.color = "black" self.win.flip() # Create dots obj = visual.DotStim( self.win, nDots=1, fieldPos=(0, 0), fieldSize=(1, 1), units="height", dotSize=(32, 32), dotLife=0, noiseDots='direction', dir=0, speed=0.25, coherence=1 ) # Draw dots obj.draw() # Get screenshot 1 screen1 = np.array(self.win._getFrame(buffer="back")) self.win.flip() # Draw again, triggering position update obj.draw() # Get screenshot 2 screen2 = np.array(self.win._getFrame(buffer="back")) self.win.flip() # Create compound screenshot with a dot in BOTH positions compound = np.clip(screen1 + screen2, 0, 255) # If dots have moved, then there should be more white on the compound screen than on either original assert compound.mean() > screen1.mean() and compound.mean() > screen2.mean(), ( "Dot stimulus does not appear to have moved across two frames." )
def make_dots(self): stimulus = visual.DotStim( win=self.mywin, units='pix', dotSize=self.dot_size, fieldSize=(800,800), #size of the field, in pixels nDots=self.num_dots, #number of dots that will be presented dir=self.dot_dir, coherence=self.dot_coherence, speed=self.dot_speed, dotLife=self.dot_life, signalDots='same' ) marker=pdm.PhotodiodeMarker() total_frames = self.pres_time*60 # total number of frames we need to present (assuming 60Hz monitor) frameN=0 while(frameN < total_frames): stimulus.draw() marker.draw_marker(self.mywin) self.mywin.flip() frameN += 1 self.mywin.close()
def test_dots(self): #NB we can't use screenshots here - just check that no errors are raised win = self.win #using init dots =visual.DotStim(win, color=(1.0,1.0,1.0), dir=270, nDots=500, fieldShape='circle', fieldPos=(0.0,0.0),fieldSize=1*self.scaleFactor, dotLife=5, #number of frames for each dot to be drawn signalDots='same', #are the signal and noise dots 'different' or 'same' popns (see Scase et al) noiseDots='direction', #do the noise dots follow random- 'walk', 'direction', or 'position' speed=0.01*self.scaleFactor, coherence=0.9) dots.draw() win.flip() str(dots) #check that str(xxx) is working #using .set() and check the underlying variable changed prevDirs = copy.copy(dots._dotsDir) prevSignals = copy.copy(dots._signalDots) prevVerticesPix = copy.copy(dots.verticesPix) dots.dir = 20 dots.coherence = 0.5 dots.fieldPos = [-0.5, 0.5] dots.speed = 0.1 * self.scaleFactor dots.opacity = 0.8 dots.contrast = 0.8 dots.draw() #check that things changed assert (prevDirs-dots._dotsDir).sum()!=0, \ "dots._dotsDir failed to change after dots.setDir()" assert prevSignals.sum()!=dots._signalDots.sum(), \ "dots._signalDots failed to change after dots.setCoherence()" assert not numpy.alltrue(prevVerticesPix==dots.verticesPix), \ "dots.verticesPix failed to change after dots.setPos()"
def make_dots(self): stimulus = visual.DotStim( win=self.mywin, units='pix', dotSize=self.dot_size, fieldSize=(800, 800), #size of the field, in pixels nDots=self.num_dots, #number of dots that will be presented dir=self.dot_dir, coherence=self.dot_coherence, speed=self.dot_speed, ) flicker_mod = 60.0 / self.flicker_freq # modulus number of frames we need to present each flicker to last to get the desired frequency total_frames = self.pres_time * 60 # total number of frames we need to present marker = pdb.PhotodiodeMarker() frameN = 0 while (frameN < total_frames): stimulus.setOpacity(0) if (frameN % (flicker_mod) == 0): stimulus.setOpacity(1) stimulus.draw() marker.draw_marker(self.mywin) self.mywin.flip() frameN += 1
def createDots(win, alpha, dc, coherence=0.5, nDots=100, I0=1): ''' Create RDK within a circular aperture to overlay on the plaids :Parameters: dir: direction in degrees, 0° is left-right, -90° is down-up ''' dp = dict(fieldShape='circle', fieldSize=20, signalDots='same', noiseDots='direction', coherence=coherence, nDots=nDots, dotSize=7, dotLife=50) col = tuple([ __normalise(I0, __get_couple(alpha), __get_couple(dc), normalisation='centering') ] * 3) # element = visual.Line(win, start=(-500,0), end=(500,0), units='pix', lineWidth=3, lineColor=col, ori=180-20) dots = visual.DotStim(win, units='deg', color=col, **dp) return dots
def test_dotsUnits(self): #to test this create a small dense circle of dots and check the circle #has correct dimensions fieldSize = numpy.array([1.0,1.0])*self.scaleFactor pos = numpy.array([0.5,0])*fieldSize dots = visual.DotStim(self.win, color=[-1.0,0.0,0.5], dotSize=5, nDots=1000, fieldShape='circle', fieldPos=pos) dots.draw() utils.compareScreenshot('dots_%s.png' %(self.contextName), self.win, crit=20) self.win.flip()
def dots_cond(coherDots,direcDots,corrDots,win,length): from psychopy import locale_setup, gui, visual, core, data, event, logging, sound from psychopy.constants import (NOT_STARTED, STARTED, PLAYING, PAUSED, STOPPED, FINISHED, PRESSED, RELEASED, FOREVER) import numpy as np # whole numpy lib is available, prepend 'np.' from numpy import (sin, cos, tan, log, log10, pi, average, sqrt, std, deg2rad, rad2deg, linspace, asarray) from numpy.random import random, randint, normal, shuffle import os # handy system and path functions import sys # to get file system encoding import csv # Stimulus setup dots = visual.DotStim( win=win,name='dots',coherence=coherDots,dir=direcDots,nDots=100, dotSize=8,speed=0.003,fieldSize=1, fieldShape='circle',signalDots='same', noiseDots='direction', dotLife=1000) # ------Prepare to start Routine "dots"------- dotsClock = core.Clock() # clock, to be used in the future response = 0 # -------Start Routine "dots"------- for i in range(90): dots.draw() win.flip() # record responses while response == 0: theseKeys = event.getKeys(keyList=['left', 'right','space','escape']) if len(theseKeys) == 0: #print 'miss' response = 3 elif len(theseKeys) > 0: if 'escape' in theseKeys: core.quit() elif 'space' in theseKeys: response = 1 elif (theseKeys[-1] == str(corrDots)) or (theseKeys[-1] == corrDots): #print 'correct!' response = 2 else: #print 'incorrect' response = 3 return response
def create_stimuli(self): self.stimuli = OrderedDict() self.stimuli['dotsBackground'] = visual.DotStim(win=self.win, nDots=500, coherence=1, fieldSize=1060, fieldShape='circle', dotSize=2.0, dotLife=100.0, speed=0, color=(-0.8, -0.8, -0.8), signalDots='same', noiseDots='direction', units='pix') self.stimuli['dotsBackground'].ori = 0 self.stimuli['circlePatch'] = visual.Circle(win=self.win, radius=240.0, pos=(0, 0), lineWidth=1, lineColor=(-1, -1, -1), fillColor=(-1, -1, -1), units='pix') self.stimuli['rodStim'] = visual.Line(win=self.win, start=(0, -100), end=(0, 100), lineWidth=5, lineColor=(-0.84, -0.84, -0.84)) self.stimuli['squareFrame'] = visual.Rect(win=self.win, width=300.0, height=300.0, pos=(0, 0), lineWidth=5, lineColor=(-0.84, -0.84, -0.84), fillColor=None, ori=0.0, units='pix') # stimulus triggers self.triggers = {} for stim in self.stimuli: self.triggers[stim] = False
def setStim(_nDots, _dotSize, _speed, _dir, _co): dots = visual.DotStim(win=win, name='dots', nDots=_nDots, dotSize=_dotSize, speed=_speed, dir=_dir, coherence=_co, fieldPos=(0.0, 0.0), fieldSize=4, fieldShape='square', signalDots='different', noiseDots='direction', dotLife=1000, color=[-1.0, -1.0, -1.0], colorSpace='rgb', opacity=1, depth=-1.0) return dots
def testDots(self): #NB we can't use screenshots here - just check that no errors are raised win = self.win contextName = self.contextName #using init dots = visual.DotStim( win, color=(1.0, 1.0, 1.0), dir=270, nDots=500, fieldShape='circle', fieldPos=(0.0, 0.0), fieldSize=1 * self.scaleFactor, dotLife=5, #number of frames for each dot to be drawn signalDots= 'same', #are the signal and noise dots 'different' or 'same' popns (see Scase et al) noiseDots= 'direction', #do the noise dots follow random- 'walk', 'direction', or 'position' speed=0.01 * self.scaleFactor, coherence=0.9) dots.draw() win.flip() #using .set() and check the underlying variable changed prevDirs = copy.copy(dots._dotsDir) prevSignals = copy.copy(dots._signalDots) prevPosRend = copy.copy(dots._fieldPosRendered) dots.setDir(20) dots.setFieldCoherence(0.5) dots.setFieldPos([-0.5, 0.5]) dots.setSpeed(0.1 * self.scaleFactor) dots.draw() #check that things changed nose.tools.assert_false( (prevDirs - dots._dotsDir).sum() == 0, msg="dots._dotsDir failed to change after dots.setDir():") nose.tools.assert_false( prevSignals.sum() == dots._signalDots.sum(), msg="dots._signalDots failed to change after dots.setCoherence()") nose.tools.assert_false( numpy.alltrue(prevPosRend == dots._fieldPosRendered), msg="dots._fieldPosRendered failed to change after dots.setPos()")
def dotsCondition(coherDots,direcDots,corrDots,win,length): # Stimulus setup dots = visual.DotStim( win=win,name='dots',coherence=coherDots,dir=direcDots,nDots=100, dotSize=8,speed=0.003,fieldSize=1, fieldShape='circle',signalDots='same', noiseDots='direction', dotLife=1000) # ------Prepare to start Routine "dots"------- dotsClock = core.Clock() response = 0 RT = 0 taskTime = length*60 # -------Start Routine "dots"------- for i in range(taskTime): dots.draw() win.flip() theseKeys = event.getKeys(keyList=['left', 'right','space','escape']) if len(theseKeys) > 0: if 'escape' in theseKeys: # quit experiment core.quit() elif 'space' in theseKeys: # quit trial response = 1 RT = dotsClock.getTime() break elif (theseKeys[-1] == str(corrDots)) or (theseKeys[-1] == corrDots): # correct response = 2 RT = dotsClock.getTime() else: # incorrect response = 3 RT = dotsClock.getTime() if response==0: response = 3 RT = dotsClock.getTime() # record responses return response, RT
dot_density = 16.7 #in deg-2 s-1 rayon_cercle = 9.0 #in deg number_of_dots = int( np.round(dot_density * np.pi * np.square(rayon_cercle) * (1 / framerate))) dotsize = 4 ## because dots.dotSize = 2*dotsize dots = visual.DotStim( win=win, name='random_dots', nDots=number_of_dots, dotSize=dotsize, #in pixels units='deg', speed=speed_deg_sec / framerate, #in degrees per frame dir=0, #in degrees --> manipulated coherence=0.0, #--> manipulated fieldPos=[0.0, 0.0], fieldSize=rayon_cercle * 2, fieldShape='circle', signalDots= 'different', # on each frame the dots constituting the signal could be the same as on the previous frame or different. If 'same', participants may determine the direction of dots based on a single dot. noiseDots= 'position', #can be set to 'direction' or 'location'. 'location' has the disadvantage that the noise dots not only have a random direction but alos a random speed (whereas signal dots have a constant speed and constant direction) dotLife=-1, #number of frames each dot lives. color=[255, 255, 255], colorSpace='rgb255') #color of the dots ## * trials handler ## possible_stim direction_array = np.array([0, 180]) #direction: 0=right, 180=left possible_stim = [[direction] for direction in direction_array] n_trial = 100 ## number of trials
#create a window to draw in myWin = visual.Window((48, 48), allowGUI=False, bitsMode=None, units='norm', winType='pyglet') #INITIALISE SOME STIMULI dotPatch = visual.DotStim( myWin, color=(1.0, 1.0, 1.0), dir=45, nDots=10, fieldShape='circle', fieldPos=(0.0, 0.0), fieldSize=1.5, dotLife=500, #number of frames for each dot to be drawn signalDots= 'different', #are the signal and noise dots 'different' or 'same' popns (see Scase et al) noiseDots= 'direction', #do the noise dots follow random- 'walk', 'direction', or 'position' speed=0.1, coherence=0.4) scrPatch = visual.PatchStim(myWin, color=0, tex=None, size=2, opacity=0.3) trialClock = core.Clock() cont = True while cont: myWin.flip(clearBuffer=True) #redraw the buffer for frameN in range(3): #quits after 20 secs scrPatch.draw() dotPatch.draw()
colorSpace='rgb', opacity=1, languageStyle='LTR', depth=0.0) # Initialize components for Routine "Dots" DotsClock = core.Clock() dots = visual.DotStim(win=win, name='dots', units='cm', nDots=120, dotSize=22, speed=0.1, dir=1.0, coherence=1, fieldPos=(0.0, 0.0), fieldSize=15, fieldShape='circle', signalDots='different', noiseDots='direction', dotLife=20, color=[1.0, 1.0, 1.0], colorSpace='rgb', opacity=1, depth=0.0) # Initialize components for Routine "wait" waitClock = core.Clock() text = visual.TextStim(win=win, name='text', text=None, font='Arial',
stepSizes=[0.05, 0.03, 0.03, 0.02, 0.02, 0.01, 0.01], nUp=1, nDown=1, minVal=0, maxVal=0.3) #will home in on the 50% threshold # initialise stimuli fixation = visual.Circle(win, size=0.25, lineColor='white', fillColor='lightGrey') rds = visual.DotStim(win, nDots=500, fieldSize=(4, 4), fieldShape='sqr', dotLife=-1, speed=0.0, dotSize=5) target = copy.copy(rds) reference = copy.copy(rds) referenceLeft = copy.copy(reference) referenceLeft.setColor([1.0, 0, 0]) referenceLeft.setFieldPos([-(info['refDisp']) / 2, 0]) referenceRight = copy.copy(reference) referenceRight.setColor([0, 0.6, 0.6]) referenceRight.setFieldPos([(info['refDisp']) / 2, 0])
feedback = visual.TextStim(win, pos=[-shift, 0], text='', color=win_info['fg_color'], height=0.6, autoLog=0) fixDot = et.fancyFixDot(win, fg_color=win_info['fg_color'], bg_color=win_info['bg_color'], size=0.4) cloud = visual.DotStim(win, fieldPos=[-shift, 0], color=win_info['fg_color'], fieldSize=rdk['cloud_size'], nDots=n_dots, dotLife=rdk['dotLife'], dotSize=rdk['size_dots'], speed=rdk['speed'], signalDots=rdk['signalDots'], noiseDots=rdk['noiseDots'], fieldShape='circle', coherence=0) middle = visual.Circle(win, size=rdk['annulus'], pos=[-shift, 0], lineColor=None, fillColor=win_info['bg_color'], autoLog=0) # reset all triggers to zero et.sendTriggers(port, 0) ####################
from __future__ import division from __future__ import print_function from psychopy import visual, event, core win = visual.Window((600, 600), allowGUI=False, winType='pyglet') # Initialize some stimuli dotPatch = visual.DotStim( win, color=(1.0, 1.0, 1.0), dir=270, nDots=500, fieldShape='circle', fieldPos=(0.0, 0.0), fieldSize=1, dotLife=5, # number of frames for each dot to be drawn signalDots='same', # are signal dots 'same' on each frame? (see Scase et al) noiseDots= 'direction', # do the noise dots follow random- 'walk', 'direction', or 'position' speed=0.01, coherence=0.9) print(dotPatch) message = visual.TextStim(win, text='Any key to quit', pos=(0, -0.5)) trialClock = core.Clock() while not event.getKeys(): dotPatch.draw() message.draw() win.flip() # make the drawn things visible
pos=[0, -5], wrapWidth=TEXT_WRAP, height=TEXT_HEIGHT, color=stimColor, colorSpace='rgb', opacity=1, depth=-1.0) dotPatch = visual.DotStim( myWin, color=(0.0, 0.0, 0.0), dir=0, nDots=200, fieldShape='square', fieldPos=(0.0, 0.0), fieldSize=8, dotLife=12000, # number of frames for each dot to be drawn signalDots='same', # are signal dots 'same' on each frame? (see Scase et al) noiseDots= 'direction', # do the noise dots follow random- 'walk', 'direction', or 'position' speed=0.00, coherence=1.0, dotSize=6.0) def display_message(win, txt, msg): """A function to display text to the experiment window. win: psychopy.visual.Window The window to write the message to.
direction = np.empty(nTrials) dirRange = np.empty(nTrials) direction_random = np.empty(nTrials) choice = np.empty(nTrials) mon = monitors.Monitor('hospital6') mon.setDistance(57) mon.setSizePix([1920, 1080]) mon.setWidth(52.71) myWin = visual.Window([600, 600], units='pixels', monitor=mon, color=(0, 0, 0)) fixation1 = visual.GratingStim(win=myWin, size=0.5, pos=[0, 0], sf=0, rgb=-1) dotsLeftstop = visual.DotStim(win=myWin, nDots=50, units='pixels', fieldSize=200, fieldShape='circle', coherence=1, dotSize=10, dir=0, speed=0, dotLife=-1) dotsLeft = visual.DotStim(win=myWin, nDots=50, units='pixels', fieldSize=200, fieldShape='circle', coherence=1, dotSize=10, dir=0, speed=2, dotLife=-1)
def runDiagnostics(self, win, verbose=False): """Return list of (key, val, msg, warn) tuple, set self.warnings All tuple elements will be of <type str>. msg can depend on val; warn==True indicates a concern. Plain text is returned, expected to be used in html <table>. Hyperlinks can be embedded as <a href="..."> """ report = [] # add item tuples in display order # get lots of info and do quick-to-render visual (want no frames drop): # for me, grating draw times are: mean 0.53 ms, SD 0.77 ms items = info.RunTimeInfo(win=win, refreshTest='grating', verbose=True, userProcsDetailed=True) totalRAM, freeRAM = items['systemMemTotalRAM'], items['systemMemFreeRAM'] warn = False if freeRAM == 'unknown': if totalRAM != 'unknown': totalRAM = "%.1fG" % (totalRAM / 1024.) msg = _translate('could not assess available physical RAM; total %s') % totalRAM report.append(('available memory', 'unknown', msg, warn)) else: msg = _translate('physical RAM available for configuration test (of %.1fG total)') % (totalRAM / 1024.) if freeRAM < 300: # in M msg = _translate('Warning: low available physical RAM for configuration test (of %.1fG total)') % (totalRAM / 1024.) warn = True report.append(('available memory', unicode(freeRAM)+'M', msg, warn)) # ----- PSYCHOPY: ----- warn = False report.append(('PsychoPy', '', '', False)) # not localized report.append(('psychopy', __version__, _translate('avoid upgrading during an experiment'), False)) report.append(('locale', items['systemLocale'], _translate('can be set in <a href="http://www.psychopy.org/general/prefs.html#application-settings-app">Preferences -> App</a>'), False)) msg = '' if items['pythonVersion'] < '2.5' or items['pythonVersion'] >= '3': msg = _translate('Warning: python 2.6 or 2.7 required; 2.5 is not supported but might work') warn = True if 'EPD' in items['pythonFullVersion']: msg += ' Enthought Python Distribution' elif 'PsychoPy2.app' in items['pythonExecutable']: msg += ' (PsychoPy StandAlone)' bits, linkage = platform.architecture() #if not bits.startswith('32'): # msg = 'Warning: 32-bit python required; ' + msg report.append(('python version', items['pythonVersion'] + ' (%s)' % bits, msg, warn)) warn = False if verbose: msg = '' if items['pythonWxVersion'] < '2.8.10': msg = _translate('Warning: wx 2.8.10 or higher required') warn = True report.append(('wx', items['pythonWxVersion'], '', warn)) report.append(('pyglet', items['pythonPygletVersion'][:32], '', False)) report.append(('rush', str(items['psychopyHaveExtRush']), _translate('for high-priority threads'), False)) # ----- VISUAL: ----- report.append(('Visual', '', '', False)) warn = False # openGL settings: msg = '' if items['openGLVersion'] < '2.': msg = _translate('Warning: <a href="http://www.psychopy.org/general/timing/reducingFrameDrops.html?highlight=OpenGL+2.0">OpenGL 2.0 or higher is ideal</a>.') warn = True report.append(('openGL version', items['openGLVersion'], msg, warn)) report.append(('openGL vendor', items['openGLVendor'], '', False)) report.append(('screen size', ' x '.join(map(str, items['windowSize_pix'])), '', False)) #report.append(('wait blanking', str(items['windowWaitBlanking']), '', False)) warn = False msg = '' if not items['windowHaveShaders']: msg = _translate('Warning: <a href="http://www.psychopy.org/general/timing/reducingFrameDrops.html?highlight=shader">Rendering of complex stimuli will be slow</a>.') warn = True report.append(('have shaders', str(items['windowHaveShaders']), msg, warn)) warn = False msg = _translate('during the drifting <a href="http://www.psychopy.org/api/visual/gratingstim.html">GratingStim</a>') if items['windowRefreshTimeMedian_ms'] < 3.3333333: msg = _translate("""Warning: too fast? visual sync'ing with the monitor seems unlikely at 300+ Hz""") warn = True report.append(('visual sync (refresh)', "%.2f ms/frame" % items['windowRefreshTimeMedian_ms'], msg, warn)) msg = _translate('SD < 0.5 ms is ideal (want low variability)') warn = False if items['windowRefreshTimeSD_ms'] > .5: msg = _translate('Warning: the refresh rate has high frame-to-frame variability (SD > 0.5 ms)') warn = True report.append(('refresh stability (SD)', "%.2f ms" % items['windowRefreshTimeSD_ms'], msg, warn)) # draw 100 dots as a minimally demanding visual test: # first get baseline frame-rate (safe as possible, no drawing): avg, sd, median = visual.getMsPerFrame(win) dots100 = visual.DotStim(win, nDots=100, speed=0.005, dotLife=12, dir=90, coherence=0.2, dotSize=8, fieldShape='circle', autoLog=False) win.recordFrameIntervals = True win.frameIntervals = [] win.flip() for i in xrange(180): dots100.draw() win.flip() msg = _translate('during <a href="http://www.psychopy.org/api/visual/dotstim.html">DotStim</a> with 100 random dots') warn = False intervalsMS = np.array(win.frameIntervals) * 1000 nTotal = len(intervalsMS) nDropped = sum(intervalsMS > (1.5 * median)) if nDropped: msg = _translate('Warning: could not keep up during <a href="http://www.psychopy.org/api/visual/dotstim.html">DotStim</a> with 100 random dots.') warn = True report.append(('no dropped frames', '%i / %i' % (nDropped, nTotal), msg, warn)) win.recordFrameIntervals = False msg = _translate('for movies') warn = False try: from pyglet.media import avbin except: # not sure what error to catch, WindowsError not found report.append(('pyglet avbin', 'import error', _translate('Warning: could not import avbin; playing movies will not work'), True)) else: ver = avbin.get_version() if sys.platform.startswith('linux'): if not (7 <= ver < 8): msg = _translate('Warning: version 7 recommended on linux (for movies)') warn = True elif not (5 <= ver < 6): msg = _translate('Warning: version 5 recommended (for movies); Visit <a href="http://code.google.com/p/avbin">download page</a> [google.com]') warn = True report.append(('pyglet avbin', unicode(ver), msg, warn)) if verbose: report.append(('openGL max vertices', str(items['openGLmaxVerticesInVertexArray']), '', False)) keyList = ['GL_ARB_multitexture', 'GL_EXT_framebuffer_object', 'GL_ARB_fragment_program', 'GL_ARB_shader_objects', 'GL_ARB_vertex_shader', 'GL_ARB_texture_non_power_of_two', 'GL_ARB_texture_float', 'GL_STEREO'] for key in keyList: val = items['openGLext.'+key] # boolean if not val: val = '<strong>' + str(val) + '</strong>' report.append((key, str(val), '', False)) # ----- AUDIO: ----- report.append(('Audio', '', '', False)) msg = '' warn = False if not 'systemPyoVersion' in items: msg = _translate('Warning: pyo is needed for sound and microphone.') warn = True items['systemPyoVersion'] = _translate('(missing)') #elif items['systemPyoVersion'] < '0.6.2': # msg = 'pyo 0.6.2 compiled with --no-messages will suppress start-up messages' report.append(('pyo', items['systemPyoVersion'], msg, warn)) # sound latencies from portaudio; requires pyo svn r1024 try: sndInputDevices = items['systemPyo.InputDevices'] warn = False if len(sndInputDevices.keys()): key = sndInputDevices.keys()[0] mic = sndInputDevices[key] if mic['name'].endswith('icroph'): mic['name'] += 'one' # portaudio (?) seems to clip to 16 chars msg = '"%s"' % mic['name'] if mic['latency'] > 0.01: msg = _translate('Warning: "%s" latency > 10ms') % mic['name'] warn = True report.append(('microphone latency', "%.4f s" % mic['latency'], msg, warn)) else: report.append(('microphone', _translate('(not detected)'),'', False)) sndOutputDevices = items['systemPyo.OutputDevices'] if len(sndOutputDevices.keys()): warn = False key = sndOutputDevices.keys()[0] spkr = sndOutputDevices[key] msg = '"%s"' % spkr['name'] if spkr['latency'] > 0.01: msg = _translate('Warning: "%s" latency > 10ms') % spkr['name'] warn = True report.append(('speakers latency', "%.4f s" % spkr['latency'], msg, warn)) else: report.append(('speakers', _translate('(not detected)'),'', False)) except KeyError: pass s2t = '<a href="http://www.psychopy.org/api/microphone.html?highlight=Speech2Text">speech-to-text</a>' msg = _translate('audio codec for %s and sound file compression') % s2t warn = False if not 'systemFlacVersion' in items: msg = _translate('Warning: flac is needed for using %s and sound compression.') % s2t +\ ' <a href="http://flac.sourceforge.net/download.html">' +\ _translate('Download</a> [sourceforge.net].') warn = True items['systemFlacVersion'] = _translate('(missing)') if verbose: report.append(('flac', items['systemFlacVersion'].lstrip('flac '), msg, warn)) # TO-DO: add microphone + playback as sound test # ----- NUMERIC: ----- report.append(('Numeric', '', '', False)) report.append(('numpy', items['pythonNumpyVersion'], _translate('vector-based (fast) calculations'), False)) report.append(('scipy', items['pythonScipyVersion'], _translate('scientific / numerical'), False)) report.append(('matplotlib', items['pythonMatplotlibVersion'], _translate('plotting; fast contains(), overlaps()'), False)) # ----- SYSTEM: ----- report.append(('System', '', '', False)) report.append(('platform', items['systemPlatform'], '', False)) msg = _translate('for online help, usage statistics, software updates, and google-speech') warn = False if items['systemHaveInternetAccess'] is not True: items['systemHaveInternetAccess'] = 'False' msg = _translate('Warning: could not connect (no proxy attempted)') warn = True # TO-DO: dlg to query whether to try to auto-detect (can take a while), or allow manual entry of proxy str, save into prefs val = str(items['systemHaveInternetAccess']) report.append(('internet access', val, msg, warn)) report.append(('auto proxy', str(self.prefs.connections['autoProxy']), _translate('try to auto-detect a proxy if needed; see <a href="http://www.psychopy.org/general/prefs.html#connection-settings-connections">Preferences -> Connections</a>'), False)) if not self.prefs.connections['proxy'].strip(): prx = ' --' else: prx = unicode(self.prefs.connections['proxy']) report.append(('proxy setting', prx, _translate('current manual proxy setting from <a href="http://www.psychopy.org/general/prefs.html#connection-settings-connections">Preferences -> Connections</a>'), False)) msg = '' warn = False # assure that we have a list if items['systemUserProcFlagged'] is None: items['systemUserProcFlagged'] = [] items['systemUserProcFlagged'].sort() self.badBgProc = [p for p,pid in items['systemUserProcFlagged']] if len(self.badBgProc): val = ("%s ..." % self.badBgProc[0]) msg = _translate('Warning: Some <a href="http://www.psychopy.org/general/timing/reducingFrameDrops.html?highlight=background+processes">background processes</a> can adversely affect timing') warn = True else: val = _translate('No bad background processes active.') report.append(('background processes', val, msg, warn)) if verbose and 'systemSec.OpenSSLVersion' in items: report.append(('OpenSSL', items['systemSec.OpenSSLVersion'].lstrip('OpenSSL '), 'for <a href="http://www.psychopy.org/api/encryption.html">encryption</a>', False)) report.append(('CPU speed test', "%.3f s" % items['systemTimeNumpySD1000000_sec'], _translate('numpy.std() of 1,000,000 data points'), False)) # TO-DO: more speed benchmarks # - load large image file from disk # - transfer image to GPU # ----- IMPORTS (relevant for developers & non-StandAlone): ----- if verbose: # always False for a real first-run report.append((_translate('Python packages'), '', '', False)) packages = ['PIL', 'openpyxl', 'lxml', 'setuptools', 'pytest', 'sphinx', 'psignifit', 'pyserial', 'pp', 'pynetstation', 'ioLabs', 'labjack' ] if sys.platform == 'win32': packages.append('pywin32') packages.append('winioport') for pkg in packages: try: if pkg == 'PIL': exec('import PIL.Image') ver = PIL.Image.VERSION #elif pkg == 'lxml': # elif pkg == 'pp': exec('import pp; ver = pp.version') elif pkg == 'pynetstation': exec('from psychopy.hardware import egi') ver = 'import ok' elif pkg == 'pyserial': exec('import serial') ver = serial.VERSION elif pkg == 'pywin32': exec('import win32api') ver = 'import ok' else: exec('import ' + pkg) try: ver = eval(pkg+'.__version__') except: ver = 'import ok' report.append((pkg, ver, '', False)) except (ImportError, AttributeError): report.append((pkg, ' --', _translate('could not import package %s') % pkg, False)) # rewrite to avoid assumption of locale en_US: self.warnings = list(set([key for key, val, msg, warn in report if warn])) return report
from psychopy import visual, misc import numpy nDots = 1000 angVelocity = 1 #deg rotation per frame win = visual.Window((600, 600)) #Ideally, we should subclass DotStim and override the _updateDots method to #what we want with the spherical rotation. But we'll just set speed and dotLife #so that they won't update (?) myStim = visual.DotStim(win, nDots=nDots, speed=0, fieldSize=[500, 500], dotLife=-1) #this is a hack #starting spherical coordinates for our dots azims = numpy.random.random(nDots) * 360 elevs = numpy.random.random(nDots) * 180 - 90 radii = 0.5 win.setRecordFrameIntervals() for frameN in range(1000): azims += angVelocity #add angVel to the azimuth of the dots x, y, z = misc.sph2cart(elevs, azims, radii) myStim._dotsXY[:, 0] = x myStim._dotsXY[:, 1] = z #?! myStim._calcDotsXYRendered()
def runLotsOfDots(self, win, fieldShape, starting=100, baseline=None): """DotStim stress test: draw increasingly many dots until drop lots of frames report best dots as the highest dot count at which drop no frames at all fieldShape = circle or square starting = initial dot count; increases until failure baseline = known frames per second; None means measure it here """ win.recordFrameIntervals = True secs = 1 # how long to draw them for, at least 1s # baseline frames per second: if not baseline: for i in xrange(5): win.flip() # wake things up win.fps() # reset for i in xrange(60): win.flip() baseline = round(win.fps()) maxFrame = round(baseline * secs) dotsInfo = [] win.flip() bestDots = starting # this might over-estimate the actual best dotCount = starting count = visual.TextStim(win, text=str(dotCount), autoLog=False) count.draw() win.flip() dots = visual.DotStim(win, color=(1.0, 1.0, 1.0), fieldShape=fieldShape, nDots=dotCount, autoLog=False) win.fps() # reset frameCount = 0 while True: dots.draw() win.flip() frameCount += 1 if frameCount > maxFrame: fps = win.fps() # get frames per sec if len(event.getKeys(['escape'])): sys.exit() if fps < baseline * 0.6: # only break when start dropping a LOT of frames (80% or more) dotsInfo.append(('dots_' + fieldShape, str(bestDots), '', False)) break frames_dropped = round(baseline-fps) # can be negative if frames_dropped < 1: # can be negative # only set best if no dropped frames: bestDots = dotCount # but do allow to continue in case do better with more dots: dotCount += 100 if dotCount > 1200: dotCount += 100 if dotCount > 2400: dotCount += 100 # show the dot count: count.setText(str(dotCount), log=False) count.draw() win.flip() dots = visual.DotStim(win, color=(1.0, 1.0, 1.0), fieldShape=fieldShape, nDots=dotCount, autoLog=False) frameCount = 0 win.fps() # reset win.recordFrameIntervals = False win.flip() return tuple(dotsInfo)
def runDiagnostics(self, win, verbose=False): """Return list of (key, val, msg, warn) tuple, set self.warnings All tuple elements will be of <type str>. msg can depend on val; warn==True indicates a concern. Plain text is returned, expected to be used in html <table>. Hyperlinks can be embedded as <a href="..."> """ report = [] # add item tuples in display order # get lots of info and do quick-to-render visual (want 0 frames drop): # for me, grating draw times are: mean 0.53 ms, SD 0.77 ms items = info.RunTimeInfo(win=win, refreshTest='grating', verbose=True, userProcsDetailed=True) totalRAM = items['systemMemTotalRAM'] freeRAM = items['systemMemFreeRAM'] warn = False if freeRAM == 'unknown': if totalRAM != 'unknown': totalRAM = "%.1fG" % (totalRAM / 1024.0) txt = _translate( 'could not assess available physical RAM; total %s') msg = txt % totalRAM report.append(('available memory', 'unknown', msg, warn)) else: txt = _translate('physical RAM available for configuration test ' '(of %.1fG total)') msg = txt % (totalRAM / 1024.) if freeRAM < 300: # in M txt = _translate('Warning: low available physical RAM for ' 'configuration test (of %.1fG total)') msg = txt % (totalRAM / 1024.) warn = True report.append(('available memory', str(freeRAM) + 'M', msg, warn)) # ----- PSYCHOPY: ----- warn = False report.append(('PsychoPy', '', '', False)) # not localized report.append( ('psychopy', __version__, _translate('avoid upgrading during an experiment'), False)) msg = _translate( 'can be set in <a href="http://www.psychopy.org/general/' 'prefs.html#application-settings-app">Preferences -> App</a>') report.append(('locale', items['systemLocale'], msg, False)) msg = '' v = parse_version thisV = v(items['pythonVersion']) if (thisV < v('2.7') or (v('3.0') <= thisV < v('3.6'))): msg = _translate("Warning: python 2.7 or 3.6 are recommended; " "2.6 and 3.5 might work. Others probably won't.") warn = True if 'EPD' in items['pythonFullVersion']: msg += ' Enthought Python Distribution' elif 'PsychoPy3.app' in items['pythonExecutable']: msg += ' (PsychoPy StandAlone)' bits, linkage = platform.architecture() # if not bits.startswith('32'): # msg = 'Warning: 32-bit python required; ' + msg report.append( ('python version', items['pythonVersion'] + ' (%s)' % bits, msg, warn)) warn = False if verbose: msg = '' if items['pythonWxVersion'] < '2.8.10': msg = _translate('Warning: wx 2.8.10 or higher required') warn = True report.append(('wx', items['pythonWxVersion'], '', warn)) report.append( ('pyglet', items['pythonPygletVersion'][:32], '', False)) report.append(('rush', str(items['psychopyHaveExtRush']), _translate('for high-priority threads'), False)) # ----- VISUAL: ----- report.append(('Visual', '', '', False)) warn = False # openGL settings: msg = '' if items['openGLVersion'] < '2.': msg = _translate( 'Warning: <a href="http://www.psychopy.org/general/timing' '/reducingFrameDrops.html?highlight=OpenGL+2.0">OpenGL ' '2.0 or higher is ideal</a>.') warn = True report.append(('openGL version', items['openGLVersion'], msg, warn)) report.append(('openGL vendor', items['openGLVendor'], '', False)) report.append( ('screen size', ' x '.join(map(str, items['windowSize_pix'])), '', False)) # report.append(('wait blanking', str(items['windowWaitBlanking']), '', # False)) warn = False msg = '' if not items['windowHaveShaders']: msg = _translate( 'Warning: <a href="http://www.psychopy.org/general/timing' '/reducingFrameDrops.html?highlight=shader">Rendering of' ' complex stimuli will be slow</a>.') warn = True report.append( ('have shaders', str(items['windowHaveShaders']), msg, warn)) warn = False msg = _translate( 'during the drifting <a href="http://www.psychopy.org/api/' 'visual/gratingstim.html">GratingStim</a>') if items['windowRefreshTimeMedian_ms'] < 3.3333333: msg = _translate( "Warning: too fast? visual sync'ing with the monitor" " seems unlikely at 300+ Hz") warn = True report.append( ('visual sync (refresh)', "%.2f ms/frame" % items['windowRefreshTimeMedian_ms'], msg, warn)) msg = _translate('SD < 0.5 ms is ideal (want low variability)') warn = False if items['windowRefreshTimeSD_ms'] > .5: msg = _translate( 'Warning: the refresh rate has high frame-to-frame ' 'variability (SD > 0.5 ms)') warn = True report.append(('refresh stability (SD)', "%.2f ms" % items['windowRefreshTimeSD_ms'], msg, warn)) # draw 100 dots as a minimally demanding visual test: # first get baseline frame-rate (safe as possible, no drawing): avg, sd, median = visual.getMsPerFrame(win) dots100 = visual.DotStim(win, nDots=100, speed=0.005, dotLife=12, dir=90, coherence=0.2, dotSize=8, fieldShape='circle', autoLog=False) win.recordFrameIntervals = True win.frameIntervals = [] win.flip() for i in range(180): dots100.draw() win.flip() msg = _translate('during <a href="http://www.psychopy.org/api/visual/' 'dotstim.html">DotStim</a> with 100 random dots') warn = False intervalsMS = np.array(win.frameIntervals) * 1000 nTotal = len(intervalsMS) nDropped = sum(intervalsMS > (1.5 * median)) if nDropped: msg = _translate( 'Warning: could not keep up during <a href="http://' 'www.psychopy.org/api/visual/dotstim.html">DotStim</a>' ' with 100 random dots.') warn = True report.append( ('no dropped frames', '%i / %i' % (nDropped, nTotal), msg, warn)) win.recordFrameIntervals = False if verbose: report.append( ('openGL max vertices', str(items['openGLmaxVerticesInVertexArray']), '', False)) keyList = ('GL_ARB_multitexture', 'GL_EXT_framebuffer_object', 'GL_ARB_fragment_program', 'GL_ARB_shader_objects', 'GL_ARB_vertex_shader', 'GL_ARB_texture_float', 'GL_ARB_texture_non_power_of_two', 'GL_STEREO') for key in keyList: val = items['openGLext.' + key] # boolean if not val: val = '<strong>' + str(val) + '</strong>' report.append((key, str(val), '', False)) # ----- AUDIO: ----- report.append(('Audio', '', '', False)) msg = '' warn = False if not 'systemPyoVersion' in items: msg = _translate( 'Warning: pyo is needed for sound and microphone.') warn = True items['systemPyoVersion'] = _translate('(missing)') # elif items['systemPyoVersion'] < '0.6.2': # msg = 'pyo 0.6.2 compiled with --no-messages will # suppress start-up messages' report.append(('pyo', items['systemPyoVersion'], msg, warn)) # TO-DO: add microphone + playback as sound test # ----- NUMERIC: ----- report.append(('Numeric', '', '', False)) report.append(('numpy', items['pythonNumpyVersion'], _translate('vector-based (fast) calculations'), False)) report.append(('scipy', items['pythonScipyVersion'], _translate('scientific / numerical'), False)) report.append( ('matplotlib', items['pythonMatplotlibVersion'], _translate('plotting; fast contains(), overlaps()'), False)) # ----- SYSTEM: ----- report.append(('System', '', '', False)) report.append(('platform', items['systemPlatform'], '', False)) msg = _translate('for online help, usage statistics, software ' 'updates, and google-speech') warn = False if items['systemHaveInternetAccess'] is not True: items['systemHaveInternetAccess'] = 'False' msg = _translate('Warning: could not connect (no proxy attempted)') warn = True # TO-DO: dlg to query whether to try to auto-detect (can take a # while), or allow manual entry of proxy str, save into prefs val = str(items['systemHaveInternetAccess']) report.append(('internet access', val, msg, warn)) report.append(('auto proxy', str(self.prefs.connections['autoProxy']), _translate('try to auto-detect a proxy if needed; see' ' <a href="http://www.psychopy.org/general' '/prefs.html#connection-settings-connection' 's">Preferences -> Connections</a>'), False)) if not self.prefs.connections['proxy'].strip(): prx = ' --' else: prx = str(self.prefs.connections['proxy']) report.append(('proxy setting', prx, _translate('current manual proxy setting from <a ' 'href="http://www.psychopy.org/general/' 'prefs.html#connection-settings-connections' '">Preferences -> Connections</a>'), False)) txt = 'CPU speed test' report.append( (txt, "%.3f s" % items['systemTimeNumpySD1000000_sec'], _translate('numpy.std() of 1,000,000 data points'), False)) # TO-DO: more speed benchmarks # - load large image file from disk # - transfer image to GPU # ----- IMPORTS (relevant for developers & non-StandAlone): ----- if verbose: # always False for a real first-run report.append((_translate('Python packages'), '', '', False)) packages = [ 'PIL', 'openpyxl', 'lxml', 'setuptools', 'pytest', 'sphinx', 'psignifit', 'pyserial', 'pp', 'pynetstation', 'labjack' ] if sys.platform == 'win32': packages.append('pywin32') packages.append('winioport') if constants.PY3: pkgError = ModuleNotFoundError else: pkgError = ImportError for pkg in packages: try: if pkg == 'PIL': import PIL ver = PIL.__version__ # elif pkg == 'lxml': # elif pkg == 'pynetstation': from psychopy.hardware import egi ver = 'import ok' elif pkg == 'pyserial': import serial ver = serial.VERSION elif pkg == 'pywin32': import win32api ver = 'import ok' else: exec('import ' + pkg) try: ver = eval(pkg + '.__version__') except Exception: ver = 'imported but no version info' report.append((pkg, ver, '', False)) except (pkgError, AttributeError): msg = _translate('could not import package %s') report.append((pkg, ' --', msg % pkg, False)) # rewrite to avoid assumption of locale en_US: self.warnings = list( set([key for key, val, msg, warn in report if warn])) return report
myWin = visual.Window((600, 600), allowGUI=False, bitsMode=None, units='norm', winType='pyglet') #INITIALISE SOME STIMULI dotPatch = visual.DotStim( myWin, color=(1.0, 1.0, 1.0), dir=0, units='pix', nDots=23, fieldShape='circle', fieldPos=(0, 0), fieldSize=100, dotSize=3, dotLife=4, #number of frames for each dot to be drawn signalDots= 'different', #are the signal dots the 'same' on each frame? (see Scase et al) noiseDots= 'position', #do the noise dots follow random- 'walk', 'direction', or 'position' speed=5, coherence=.5) message = visual.TextStim(myWin, text='Hit Q to quit', pos=(0, -0.5)) trialClock = core.Clock() while True: #forever dotPatch.draw() message.draw() myWin.flip() #redraw the buffer
from psychopy import core, event, visual, sound, gui gui = gui.Dlg() gui.addField("Participant Number:") gui.addField("Name:") gui.show() subject_id = gui.data[0] subject_name = gui.data[1] n_blocks = 10 # win = visual.Window([1200,800], fullscr=True, color=[-1,-1,-1]) win = visual.Window([1200, 800], color=[-1, -1, -1]) stars = visual.DotStim(win, dir=1, nDots=100, fieldSize=(2, 2)) ship = visual.ImageStim(win, image='resources/images/ship.png', size=0.4) asteroid = visual.ImageStim(win, 'resources/images/asteroid.png', pos=(0, 1), size=0.2) laser = visual.ImageStim(win, image='resources/images/beams.png', size=0.3, pos=(-0.15, 0.1)) splash_title = visual.ImageStim(win, image="resources/images/splash.png", opacity=0) score = visual.TextStim(win,
isitext1.draw() win.flip() ############################ # The right patch ############################ # Initialize some stimuli for Patch 1A # UNDER PATCH dotPatch1A = visual.DotStim( win, color='white', dir=direction1a, nDots=85, fieldShape='sqr', fieldPos=(8.0, 0.0), fieldSize=6, dotLife=30, # number of frames for each dot to be drawn signalDots='same', # are signal dots 'same' on each frame? noiseDots= 'direction', # do the noise dots follow random- 'walk', 'direction', or 'position' speed=0.09, coherence=1, dotSize=5) # Initialize some stimuli for Patch 1B (proportion patch) # oVER PATCH dotPatch1B = visual.DotStim( win, color='red', dir=direction1b, nDots=15, fieldShape='sqr',
win = visual.Window(fullscr=True, screen=0, allowGUI=False, bitsMode=None, units='pix', winType='pyglet') dotPatch1 = visual.DotStim( win, units='pix', color=(1.0, 1.0, 1.0), nDots=NrOfDots, dotSize=5, fieldShape='circle', fieldPos=pos1, fieldSize=(350, 350), dotLife=180, #number of frames for each dot to be drawn speed=0, dir=randdir1, coherence=1, signalDots='same', noiseDots='direction') newArray = np.array([random.uniform(0., 360.) for r in xrange(NrOfDots)]) dotPatch1._dotsDir = newArray dirChange = random.uniform(-0.1, 0.1) turncounter = 0 turndeg = random.randint(30, 90)