def __init__(self, experiment): self.fixSpot_null = visual.PatchStim(experiment.myWin, tex="none", mask="circle", pos=(0, experiment.origin), size=(0.5, 0.5), color='white', autoLog=False) self.fixSpot_FB = visual.PatchStim(experiment.myWin, tex="none", mask="circle", pos=(0, experiment.origin), size=(0.5, 0.5), color='red', autoLog=False) print experiment.subjectID
def ellipse(self, x, y, w, h, fill=False, color=None): """ Draws an ellipse. Should accept parameters where w < 0 or h < 0 as well. Arguments: x -- The left X coordinate. y -- The top Y coordinate. w -- The width. h -- The height. Keyword arguments: fill -- A boolean indicating whether the ellipse is outlined (False) or filled (True) color -- A custom human readable foreground color. This does not affect the default foreground color as set by set_fgcolor(). (Default = None) """ if color != None: color = self.color(color) else: color = self.fgcolor pos = x - self.xcenter() + w / 2, self.ycenter() - y - h / 2 stim = visual.PatchStim(win=self.experiment.window, mask="circle", pos=pos, size=[w, h], color=color, tex=None, interpolate=True) self.stim_list.append(stim) if not fill: stim = visual.PatchStim( win=self.experiment.window, mask="circle", pos=pos, size=[w - 2 * self.penwidth, h - 2 * self.penwidth], color=self.bgcolor, tex=None, interpolate=True) self.stim_list.append(stim)
def noise_patch(self, x, y, env="gaussian", size=96, stdev=12, \ col1="white", col2="black", bgmode="avg"): """See openexp._canvas.legacy""" pos = x - self.xcenter(), self.ycenter() - y _env, _size, s = self.env_to_mask(env, size, stdev) tex = 2*(np.random.random([s,s])-0.5) p = visual.PatchStim(win=self.experiment.window, tex=tex, pos=pos, mask=_env, size=_size, color=col1) self.stim_list.append(p)
def ellipse(self, x, y, w, h, fill=False, color=None): """See openexp._canvas.legacy""" if color != None: color = self.color(color) else: color = self.fgcolor pos = x - self.xcenter() + w / 2, self.ycenter() - y - h / 2 stim = visual.PatchStim(win = self.experiment.window, mask="circle", \ pos=pos, size=[w, h], color=color, tex=None, interpolate=True) self.stim_list.append(stim) if not fill: stim = visual.PatchStim(win = self.experiment.window, \ mask="circle", pos=pos, size=[w-2*self.penwidth, \ h-2*self.penwidth], color=self.bgcolor, tex=None, \ interpolate=True) self.stim_list.append(stim)
def __init__(self, tracker, display, displaySize): '''Initialize a Custom EyeLinkCoreGraphics for Psychopy tracker: the TRACKER() object display: the Psychopy display window''' pylink.EyeLinkCustomDisplay.__init__(self) self.display = display self.displaySize = displaySize self.tracker = tracker self.mouse = event.Mouse(visible=False) self.target = visual.PatchStim(display, tex = None, mask = 'circle',units='pix', pos=(0,0),size=(6,6), color = [1,1,1] ) # calibrating dot print("Finished initializing custom graphics")
def createPsychoGraphicsWindow(self): #create a window self.psychoWindow = visual.Window(self.display.getPixelResolution(), monitor=self.display.getPsychopyMonitorName(), units=self.display.getCoordinateType(), color=[128,128,128], colorSpace='rgb255', fullscr=True, allowGUI=False, screen=self.display.getIndex() ) currentPosition=self.mouse.setPosition((0,0)) self.mouse.setSystemCursorVisibility(False) fixation = visual.PatchStim(self.psychoWindow, size=25, pos=[0,0], sf=0, color=[-1,-1,-1], colorSpace='rgb') title = visual.TextStim(win=self.psychoWindow, text="ioHub getEvents Delay Test", pos = [0,125], height=36, color=[1,.5,0], colorSpace='rgb', alignHoriz='center', wrapWidth=800.0) instr = visual.TextStim(win=self.psychoWindow, text='Move the mouse around, press keyboard keys and mouse buttons', pos = [0,-125], height=32, color=[-1,-1,-1], colorSpace='rgb',alignHoriz='center',wrapWidth=800.0) self.psychoStim['static'] = visual.BufferImageStim(win=self.psychoWindow, stim=(fixation, title, instr)) self.psychoStim['grating'] = visual.PatchStim(self.psychoWindow, mask="circle", size=75,pos=[-100,0], sf=.075) self.psychoStim['keytext'] = visual.TextStim(win=self.psychoWindow, text='key', pos = [0,300], height=48, color=[-1,-1,-1], colorSpace='rgb', alignHoriz='left',wrapWidth=800.0) self.psychoStim['mouseDot'] = visual.GratingStim(win=self.psychoWindow, tex=None, mask="gauss", pos=currentPosition,size=(50,50), color='purple') self.psychoStim['progress'] = visual.ShapeStim(win=self.psychoWindow, vertices=[(0,0),(0,0),(0,0),(0,0)], pos=(400, -300))
def PatchGlob(self, path, picType, window=None, Size=None, Position=[0, 0]): # used to obtain all pictures beginning with a certain path and append them to a list for later use. """Takes the idea that you have images named something akin to "F1.jpg, F2.jpg, F3.jpg..." and runs with it. In path you write the path to the directory with the images, with a \F or whatever at the end. In picType you add '.jpg' for jpegs and so on. The Size and Position are variables that can be altered to suit your purposes, but by default are the natural image size and the center of the screen. This function then fills a list with psychopy ImageStims of all those images, using the psychopy visual.Window given by the window argument. Feel free to alter the window, image function, and so on.""" List = [] # You don't have to make empty lists for this function to fill in the script itself stims = glob.glob( path + '*' + picType) # basically this searches for anything starting with the path and ending in the picType. While it's possible to specify a path as part of this function, it removes the location flexibility. for stim in stims: # for all the files found List.append(visual.PatchStim(window, tex=stim, mask=None, pos=Position, size=Size)) # add to the list the PatchStim object, meaning it can be drawn and we don't have to do this within any other function. return List
def test_auto_draw(self): win = self.win stims = [] stims.append(visual.PatchStim(win)) stims.append(visual.ShapeStim(win)) stims.append(visual.TextStim(win)) for stim in stims: assert stim.status == visual.NOT_STARTED stim.setAutoDraw(True) assert stim.status == visual.STARTED stim.setAutoDraw(False) assert stim.status == visual.FINISHED assert stim.status == visual.STOPPED
def __init__(self, win, filename="TEST.EDF"): self.win = win EyeLink.__init__(self) self._filename = filename self.openDataFile(filename) #EyeLinkCustomDisplay.__init__(self) self._surfs = pygame.display.get_surface() pylink.flushGetkeyQueue() col = 128 pylink.setCalibrationColors((0, 0, 0), (col, col, col)) #Sets the calibration target and background color self.sendCommand("screen_pixel_coords = 0 0 %d %d" % (self._surfs.get_width(), self._surfs.get_height())) self.sendMessage("DISPLAY_COORDS 0 0 %d %d" % (self._surfs.get_width(), self._surfs.get_height())) self.sendCommand("select_parser_configuration 0") self.setFileEventFilter("LEFT,RIGHT,FIXATION,SACCADE,BLINK,MESSAGE,BUTTON") self.setFileSampleFilter("LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS") self.setLinkEventFilter("LEFT,RIGHT,FIXATION,SACCADE,BLINK,BUTTON") self.setLinkSampleFilter("LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS") self.sendCommand("button_function 5 'accept_target_fixation'") self.inner = visual.PatchStim(win, tex = None, mask = 'circle', units = 'pix', size = 5, color = win.color) self.outer = visual.PatchStim(win, tex = None, mask = 'circle', units = 'pix', size = 20, color = [128,128,128])
def test_aperture(self): win = self.win if not win.allowStencil: pytest.skip("Don't run aperture test when no stencil is available") grating = visual.PatchStim(win, mask='gauss',sf=8.0, size=2,color='FireBrick', units='norm') aperture = visual.Aperture(win, size=1*self.scaleFactor,pos=[0.8*self.scaleFactor,0]) aperture.disable() grating.draw() aperture.enable() grating.setOri(90) grating.setColor('black') grating.draw() utils.compareScreenshot('aperture1_%s.png' %(self.contextName), win)
def test_auto_draw(self): win = self.win stims = [] stims.append(visual.PatchStim(win)) stims.append(visual.ShapeStim(win)) stims.append(visual.TextStim(win)) for stim in stims: assert stim.status == visual.NOT_STARTED stim.autoDraw = True assert stim.status == visual.STARTED stim.autoDraw = False assert stim.status == visual.FINISHED assert stim.status == visual.STOPPED str(stim) #check that str(xxx) is working
def test_bufferImage(self): """BufferImage inherits from ImageStim, so test .ori. .pos etc there not here """ win = self.win gabor = visual.PatchStim(win, mask='gauss', ori=-45, pos=[0.6*self.scaleFactor, -0.6*self.scaleFactor], sf=2.0/self.scaleFactor, size=2*self.scaleFactor, interpolate=True) bufferImgStim = visual.BufferImageStim(self.win, stim=[gabor], interpolate=True) bufferImgStim.draw() utils.compareScreenshot('bufferimg_gabor_%s.png' %(self.contextName), win, crit=8) win.flip()
def gabor(self, x, y, orient, freq, env="gaussian", size=96, stdev=12, \ phase=0, col1="white", col2=None, bgmode=None): """See openexp._canvas.legacy""" pos = x - self.xcenter(), self.ycenter() - y _env, _size, s = self.env_to_mask(env, size, stdev) p = visual.PatchStim(win=self.experiment.window, pos=pos, ori=-orient, mask=_env, size=_size, sf=freq, phase=phase, color=col1) self.stim_list.append(p)
def __init__(self, window): self.window = window self.keys = [] if sys.byteorder == 'little': self.byteorder = 1 else: self.byteorder = 0 pylink.EyeLinkCustomDisplay.__init__(self) self.__target_beep__ = None self.__target_beep__done__ = None self.__target_beep__error__ = None self.imagebuffer = array.array('I') self.pal = None self.width, self.height = window.size self.pos = [] self.state = 0 self.inner = visual.PatchStim(window, tex=None, mask='circle', units='pix', size=5, color=window.color) self.outer = visual.PatchStim(window, tex=None, mask='circle', units='pix', size=20, color=[128, 128, 128]) self.image_patch = visual.PatchStim(window) self.label = None
def __init__(self, win, name=None, autoLog=None, depth=-10000): self.win = win self.depth = depth super(PenPositionStim, self).__init__(name, autoLog) # Pen Hovering Related # Opaticy is changed based on pen's z axis if data for z axis # is available. Opacity of min_opacity is used when pen is at the # furthest hover distance (z value) supported by the device. # Opacity of 1.0 is used when z value == 0, meaning pen is touching # digitizer surface. self.min_opacity = 0.0 # If z axis is supported, hover_color specifies the color of the pen # position dot when z val > 0. self.hover_color = 'red' # Pen Pressure Related # Smallest radius (in norm units) that the pen position gaussian blob # will have, which occurs when pen pressure value is 0 self.min_size = 0.033 # As pen pressure value increases, so does position gaussian blob # radius (in norm units). Max radius is reached when pressure is # at max device pressure value, and is equal to min_size+size_range self.size_range = 0.1666 # Color of pen position blob when pressure > 0. self.touching_color = 'green' # Pen tilt Related # Color of line graphic used to represent the pens tilt relative to # the digitizer surface. self.tiltline_color = (1, 1, 0) # Create a Gausian blob stim to use for pen position graphic self.pen_guass = visual.PatchStim(win, units='norm', tex='none', mask='gauss', pos=(0, 0), size=(self.min_size,self.min_size), color=self.hover_color, autoLog=False, opacity=0.0) # Create a line stim to use for pen position graphic self.pen_tilt_line = visual.Line(win, units='norm', start=[0, 0], end=[0.5, 0.5], lineColor=self.tiltline_color, opacity=0.0)
def rect(self, x, y, w, h, fill=False, color=None): """See openexp._canvas.legacy""" if color == None: color = self.fgcolor else: color = self.color(color) if not fill: self.shapestim( [[x, y], [x+w, y], [x+w, y+h], [x, y+h]], color, \ close=True) else: pos = x + w / 2 - self.xcenter(), self.ycenter() - y - h / 2 stim = visual.PatchStim(win = self.experiment.window, pos=pos, \ size=[w, h], color=color, tex=None, interpolate=False) self.stim_list.append(stim)
def waitingAnimation(win, size=20, distanceBetweenElements=3, numElements=8, delay=1.0): totalWidth = numElements * (size + distanceBetweenElements) positions = range(totalWidth / -2, totalWidth / 2, (size + distanceBetweenElements)) for curFrame in range(numElements, -1, -1): for curElement in range(curFrame): visual.PatchStim(win, color='white', size=size, tex='None', mask='circle', pos=[positions[curElement], 0]).draw() win.flip() core.wait(delay)
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 testAperture(self): win = self.win contextName = self.contextName grating = visual.PatchStim(win, mask='gauss', sf=8.0, size=2, color='FireBrick', units='norm') aperture = visual.Aperture(win, size=1 * self.scaleFactor, pos=[0.8 * self.scaleFactor, 0]) aperture.disable() grating.draw() aperture.enable() grating.setOri(90) grating.setColor('black') grating.draw() utils.compareScreenshot('aperture1_%s.png' % (contextName), win)
def gabor(self, x, y, orient, freq, env="gaussian", size=96, stdev=12, phase=0, col1="white", col2=None, bgmode=None): """ Draws a Gabor patch. Arguments: x -- The center X coordinate y -- The center Y coordinate orient -- Orientation in degrees [0 .. 360] freq -- Frequency in cycles/px of the sinusoid Keyword arguments: env -- Any of the following: "gaussian", "linear", "circular", "rectangle" (default = "gaussian") size -- Size in pixels (default = 96) stdev -- Standard deviation in pixels of the gaussian. Only applicable if env = "gaussian". (default = 12) phase -- Phase of the sinusoid [0.0 .. 1.0] (default = 0) col1 -- Human readable color for the tops (default = "white") col2 -- Human readable color for the troughs (default = "black") bgmode -- Specifies whether the background is the average of col1 and col2 (bgmode = "avg", a typical Gabor patch) or equal to col2 ("col2"), useful for blending into the background. (default = "avg") """ pos = x - self.xcenter(), self.ycenter() - y _env, _size, s = self.env_to_mask(env, size, stdev) p = visual.PatchStim(win=self.experiment.window, pos=pos, ori=-orient, mask=_env, size=_size, sf=freq, phase=phase, color=col1) self.stim_list.append(p)
def test_gabor(self): win = self.win #using init gabor = visual.PatchStim(win, mask='gauss', ori=-45, pos=[0.6*self.scaleFactor, -0.6*self.scaleFactor], sf=2.0/self.scaleFactor, size=2*self.scaleFactor, interpolate=True) gabor.draw() utils.compareScreenshot('gabor1_%s.png' %(self.contextName), win) win.flip()#AFTER compare screenshot #using .set() gabor.setOri(45) gabor.setSize(0.2*self.scaleFactor, '-') gabor.setColor([45,30,0.3], colorSpace='dkl') gabor.setSF(0.2/self.scaleFactor, '+') gabor.setPos([-0.5*self.scaleFactor,0.5*self.scaleFactor],'+') gabor.setContrast(0.8) gabor.setOpacity(0.8) gabor.draw() utils.compareScreenshot('gabor2_%s.png' %(self.contextName), win)
def image(self, fname, center=True, x=None, y=None, scale=None): """ Draws an image from file. This function does not look in the file pool, but takes an absolute path. Arguments: fname -- The path of the file Keyword arguments: center -- A boolean indicating whether the given coordinates reflect the center (True) or the top-left (False) of the image. (default = True) x -- The X coordinate. None = center. (default = None) y -- The Y coordinate. None = center. (default = None) scale -- The scaling factor of the image. 1.0 or None = no scaling, 2.0 = twice as large, etc. (default = None) """ im = Image.open(fname) if scale != None: w = im.size[0] * scale h = im.size[1] * scale else: w, h = im.size # Calculate the position if x == None: x = self.xcenter() if y == None: y = self.ycenter() if not center: x += w / 2 y += h / 2 pos = x - self.xcenter(), self.ycenter() - y stim = visual.PatchStim(win=self.experiment.window, tex=fname, pos=pos, size=(w, h)) self.stim_list.append(stim)
def test_gabor(self): win = self.win #using init gabor = visual.PatchStim(win, mask='gauss', ori=-45, pos=[0.6*self.scaleFactor, -0.6*self.scaleFactor], sf=2.0/self.scaleFactor, size=2*self.scaleFactor, interpolate=True) gabor.draw() utils.compareScreenshot('gabor1_%s.png' %(self.contextName), win) win.flip()#AFTER compare screenshot #using .set() gabor.ori = 45 gabor.size -= 0.2 * self.scaleFactor gabor.setColor([45,30,0.3], colorSpace='dkl') gabor.sf += 0.2 / self.scaleFactor gabor.pos += [-0.5*self.scaleFactor, 0.5*self.scaleFactor] gabor.contrast = 0.8 gabor.opacity = 0.8 gabor.draw() utils.compareScreenshot('gabor2_%s.png' %(self.contextName), win) win.flip() str(gabor) #check that str(xxx) is working
def noise_patch(self, x, y, env="gaussian", size=96, stdev=12, col1="white", col2="black", bgmode="avg"): """ Draws a patch of noise, with an envelope. Arguments: x -- The center X coordinate y -- The center Y coordinate Keyword arguments: env -- Any of the following: "gaussian", "linear", "circular", "rectangle" (default = "gaussian") size -- Size in pixels (default = 96) stdev -- Standard deviation in pixels of the gaussian. Only applicable if env = "gaussian". (default = 12) phase -- Phase of the sinusoid [0.0 .. 1.0] (default = 0) col1 -- Human readable color for the tops (default = "white") col2 -- Human readable color for the troughs (default = "black") bgmode -- Specifies whether the background is the average of col1 and col2 (bgmode = "avg", a typical Gabor patch) or equal to col2 ("col2"), useful for blending into the background. (default = "avg") """ pos = x - self.xcenter(), self.ycenter() - y _env, _size, s = self.env_to_mask(env, size, stdev) tex = 2 * (np.random.random([s, s]) - 0.5) p = visual.PatchStim(win=self.experiment.window, tex=tex, pos=pos, mask=_env, size=_size, color=col1) self.stim_list.append(p)
def image(self, fname, center=True, x=None, y=None, scale=None): """See openexp._canvas.legacy""" im = Image.open(fname) if scale != None: w = im.size[0] * scale h = im.size[1] * scale else: w, h = im.size # Calculate the position if x == None: x = self.xcenter() if y == None: y = self.ycenter() if not center: x += w / 2 y += h / 2 pos = x - self.xcenter(), self.ycenter() - y stim = visual.PatchStim(win = self.experiment.window, tex=fname, \ pos=pos, size=(w,h)) self.stim_list.append(stim)
def test_gabor(self): win = self.win #using init gabor = visual.PatchStim( win, mask='gauss', ori=-45, pos=[0.6 * self.scaleFactor, -0.6 * self.scaleFactor], sf=2.0 / self.scaleFactor, size=2 * self.scaleFactor, interpolate=True, autoLog=False) gabor.draw() utils.compareScreenshot('gabor1_%s.png' % (self.contextName), win) win.flip() #AFTER compare screenshot #did buffer image also work? #bufferImgStim = visual.BufferImageStim(self.win, stim=[gabor]) #bufferImgStim.draw() #utils.compareScreenshot('gabor1_%s.png' %(self.contextName), win) #win.flip() #using .set() gabor.setOri(45, log=False) gabor.setSize(0.2 * self.scaleFactor, '-', log=False) gabor.setColor([45, 30, 0.3], colorSpace='dkl', log=False) gabor.setSF(0.2 / self.scaleFactor, '+', log=False) gabor.setPos([-0.5 * self.scaleFactor, 0.5 * self.scaleFactor], '+', log=False) gabor.setContrast(0.8, log=False) gabor.setOpacity(0.8, log=False) gabor.draw() utils.compareScreenshot('gabor2_%s.png' % (self.contextName), win) win.flip() str(gabor) #check that str(xxx) is working
#present for a certain number of frames. For that to work you need #your window flips to synchronise to the monitor and not to drop #any frames. This script examines the precision of your frame flips. #Shut down as many applications as possible, especially those that #might try to update from psychopy import visual, log, core, event import matplotlib matplotlib.use('WXAgg') import pylab nIntervals=1000 win = visual.Window([1280,1024], fullscr=True, allowGUI=False) progBar = visual.PatchStim(win, tex=None, mask=None, size=[0,0.05],color='red',pos=[0,-0.9], autoLog=False) myStim = visual.PatchStim(win, tex='sin', mask='gauss', size=300,sf=0.05, units='pix', autoLog=False) #log.console.setLevel(log.INFO)#uncomment if you want to print every frame time win.setRecordFrameIntervals() for frameN in range(nIntervals+1): progBar.setSize([2.0*frameN/nIntervals, 0.05]) progBar.draw() myStim.setPhase(0.1,'+') myStim.draw() if event.getKeys(): print 'stopped early' break
'a') #a simple text file with 'comma-separated-values' #dataFile = open(fileName+'.txt', 'a') dataFile.write( 'word, cue, stimulus, condition,distractorType, subjectResp, accuracy, RT\n' ) # Create a visual window: #win = visual.Window(fullscr=True, allowGUI = True, monitor = 'testmonitor', units = 'deg') win = visual.Window(fullscr=True, allowGUI=True, monitor='2wordTasks', units='deg') win.mouseVisible = False fixation = visual.PatchStim(win, color=-1, tex=None, mask='circle', size=0.2, units='deg') maskRight = visual.GratingStim(win=win, units="deg", size=7, pos=(4, 0), sf=5.0 / 7) maskLeft = visual.GratingStim(win=win, units="deg", size=7, pos=(-4, 0), sf=5.0 / 7) #mask.sf = 5.0 / 7 #Feedback
if showRefreshMisses: fixSizePix = 32 # 2.6 #make fixation bigger so flicker more conspicuous else: fixSizePix = 32 fixColor = [1, 1, 1] if exportImages: fixColor = [0, 0, 0] # Can counterphase flicker noise texture to create salient flicker if you break fixation fixatnNoiseTexture = np.round( np.random.rand(int(fixSizePix / 4), int(fixSizePix / 4)), 0) * 2.0 - 1 fixation = visual.PatchStim(myWin, tex=fixatnNoiseTexture, size=(fixSizePix, fixSizePix), units='pix', mask='circle', interpolate=False, autoLog=False) fixationBlank = visual.PatchStim(myWin, tex=-1 * fixatnNoiseTexture, size=(fixSizePix, fixSizePix), units='pix', mask='circle', interpolate=False, autoLog=False) # reverse contrast oddBallDur = [] # SETTING THE CONDITIONS conditions = np.array([
if params['direction'] in ['cw', 'ccw']: #create an instance of our wedge wedge = SlidingWedge(myWin, pos=params['centre'], size=params['size'], dutyCycle=params['dutyCycleWedge']) else: annulus = SlidingAnnulus(myWin, pos=params['centre'], size=params['size'], dutyCycle=params['dutyCycleAnn']) #always need a fixation point fixation = visual.PatchStim(myWin, mask='circle', tex=None, size=0.1, pos=params['centre']) #get rotation speed in deg/sec if params['direction'] == 'cw': cycleSpeed = 360.0 / params['cycleTime'] elif params['direction'] == 'ccw': cycleSpeed = -360.0 / params['cycleTime'] elif params['direction'] == 'exp': cycleSpeed = -1.0 / params['cycleTime'] elif params['direction'] == 'con': cycleSpeed = 1.0 / params['cycleTime'] def quit():