示例#1
0
    def updateparams(self, i):
        """Updates stimulus parameters, given sweep table index i"""
        if i == None: # do a blank sweep
            self.tsp.on = False # turn off the movie, leave all other parameters unchanged
            self.postval = C.MAXPOSTABLEINT # posted to DT port to indicate a blank sweep
            self.nvsyncs = sec2intvsync(self.blanksweeps.sec) # this many vsyncs for this sweep
            self.npostvsyncs = 0 # this many post-sweep vsyncs for this sweep, blank sweeps have no post-sweep delay
        else: # not a blank sweep
            self.tsp.on = True # ensure texture stimulus is on
            self.postval = i # sweep table index will be posted to DT port
            self.nvsyncs = sec2intvsync(self.st.sweepSec[i]) # this many vsyncs for this sweep
            self.npostvsyncs = sec2intvsync(self.st.postsweepSec[i]) # this many post-sweep vsyncs for this sweep

            # Update texture
            frame = self.frames[self.st.framei[i]] # get the frame for this sweep
            #frame = self[self.st.framei[i]] # get the frame for this sweep
            if self.st.invert[i]:
                frame = 255 - frame # give the frame inverted polarity
            self.to.put_sub_image(frame, data_format=gl.GL_LUMINANCE, data_type=gl.GL_UNSIGNED_BYTE)

            # Update texturestimulus
            self.tsp.angle = self.static.orioff + self.st.ori[i]
            self.tsp.position = self.xorig+deg2pix(self.st.xposDeg[i]), self.yorig+deg2pix(self.st.yposDeg[i])

            # Update background parameters
            self.bgp.color = self.st.bgbrightness[i], self.st.bgbrightness[i], self.st.bgbrightness[i], 1.0

            # Update fixationspot
            self.fsp.on = bool(self.st.fixationspotDeg[i])
            self.fsp.size = deg2pix(self.st.fixationspotDeg[i]), deg2pix(self.st.fixationspotDeg[i])
示例#2
0
    def updateparams(self, i):
        """Updates stimulus parameters, given sweep table index i"""
        if i == None: # do a blank sweep
            self.tp.on = False # turn off the target, leave all other parameters unchanged
            self.postval = C.MAXPOSTABLEINT # posted to DT port to indicate a blank sweep
            self.nvsyncs = sec2intvsync(self.blanksweeps.sec) # this many vsyncs for this sweep
            self.npostvsyncs = 0 # this many post-sweep vsyncs for this sweep, blank sweeps have no post-sweep delay
        else: # not a blank sweep
            self.tp.on = True # ensure stimulus is on
            self.postval = i # sweep table index will be posted to DT port
            self.nvsyncs = sec2intvsync(self.st.sweepSec[i]) # this many vsyncs for this sweep
            self.npostvsyncs = sec2intvsync(self.st.postsweepSec[i]) # this many post-sweep vsyncs for this sweep

            # Update target position
            ori = self.static.orioff + self.st.ori[i]
            theta = ori / 180 * pi

            dxi = self.st.xi[i] - self.xi0 # destination index - origin index
            dyi = self.st.yi[i] - self.yi0
            sintheta = math.sin(theta)
            costheta = math.cos(theta)
            dx = dxi*self.barWidth*costheta - dyi*self.barHeight*sintheta # see SparseNoise.png for the trigonometry
            dy = dxi*self.barWidth*sintheta + dyi*self.barHeight*costheta

            x = self.xorig + deg2pix(self.st.xposDeg[i]) + dx
            y = self.yorig + deg2pix(self.st.yposDeg[i]) + dy
            self.tp.position = (x, y)

            # Update non-positional target parameters
            self.tp.orientation = ori
            self.tp.color = self.st.brightness[i], self.st.brightness[i], self.st.brightness[i], 1.0
            self.tp.anti_aliasing = self.st.antialiase[i]

            # Update background parameters
            self.bgp.color = self.st.bgbrightness[i], self.st.bgbrightness[i], self.st.bgbrightness[i], 1.0
示例#3
0
    def updateparams(self, i):
        """Updates stimulus parameters, given sweep table index i"""
        if i == None: # do a blank sweep
            self.tp.on = False # turn off the target, leave all other parameters unchanged
            self.postval = C.MAXPOSTABLEINT # posted to DT port to indicate a blank sweep
            self.nvsyncs = sec2intvsync(self.blanksweeps.sec) # this many vsyncs for this sweep
            self.npostvsyncs = 0 # this many post-sweep vsyncs for this sweep, blank sweeps have no post-sweep delay
        else: # not a blank sweep
            self.tp.on = True # ensure stimulus is on
            self.postval = i # sweep table index will be posted to DT port
            self.nvsyncs = sec2intvsync(self.st.sweepSec[i]) # this many vsyncs for this sweep
            self.npostvsyncs = sec2intvsync(self.st.postsweepSec[i]) # this many post-sweep vsyncs for this sweep

            # Generate position as a f'n of vsynci for this sweep, even if speedDegSec is 0
            distance = degSec2pixVsync(self.st.speedDegSec[i]) * self.nvsyncs # total distance to travel on this sweep
            direction = self.static.orioff + self.st.ori[i] + 90 # direction to travel on this sweep, always |_ to current ori
            xdistance = distance * math.cos(direction / 180 * math.pi)
            ydistance = distance * math.sin(direction / 180 * math.pi)
            xstep = xdistance / self.nvsyncs # pix to travel per vsync
            ystep = ydistance / self.nvsyncs
            x0 = self.xorig - xdistance / 2
            y0 = self.yorig - ydistance / 2
            self.x = x0 + xstep * np.arange(self.nvsyncs) + deg2pix(self.st.xposDeg[i]) # deg2pix returns 0 if deg is None
            self.y = y0 + ystep * np.arange(self.nvsyncs) + deg2pix(self.st.yposDeg[i])

            # Update non-positional target parameters
            self.tp.orientation = self.static.orioff + self.st.ori[i]
            self.tp.size = deg2pix(self.st.widthDeg[i]), deg2pix(self.st.heightDeg[i])
            self.tp.color = self.st.rbrightness[i], self.st.gbrightness[i], self.st.bbrightness[i], 1.0
            self.tp.anti_aliasing = self.st.antialiase[i]

            # Update background parameters
            self.bgp.color = self.st.bgbrightness[i], self.st.bgbrightness[i], self.st.bgbrightness[i], 1.0
示例#4
0
 def calcduration(self):
     """Calculates how long this Experiment should take, in sec"""
     i = self.sweeptable.i
     # convert all times to vsyncs, add 'em up, then convert back. This takes into account discretization from sec to vsync
     try:
         blanksweepvsyncs = sec2intvsync(self.blanksweeps.sec) * list(i).count(None)
     except AttributeError: # blanksweeps are None, None has no .sec attrib
         blanksweepvsyncs = 0
     notblank = np.int32(i[np.not_equal(i, None)]) # sweep table indices that aren't blank sweeps, i was an object array due to Nones in it
     nvsyncs = sec2intvsync(self.static.preexpSec) + \
               np.asarray([ sec2intvsync(sweeptime) for sweeptime in self.st.sweepSec[notblank] ]).sum() + \
               np.asarray([ sec2intvsync(postsweeptime) for postsweeptime in self.st.postsweepSec[notblank] ]).sum() + \
               blanksweepvsyncs + \
               sec2intvsync(self.static.postexpSec)
     return vsync2sec(nvsyncs)
示例#5
0
    def __init__(self, script, params):
        self.script = script.replace("\\", C.SLASH).replace(
            ".pyc", ".py"
        )  # Experiment script file name, with stuff cleaned up
        self.script = os.path.splitdrive(self.script)[-1]  # strip the drive name from the start
        self.params = params
        self.params.check()
        for paramname, paramval in params.items():
            setattr(self, paramname, paramval)  # bind all parameter names to self

        if not self.flash:  # DW
            self.flashSec = 0

        self.flashvsyncs = sec2intvsync(self.flashSec)
        eye = dc.get("Eye", "open")
        # Init signals
        self.squarelock, self.brightenText = False, False
        self.UP, self.DOWN, self.LEFT, self.RIGHT = False, False, False, False
        self.PLUS, self.MINUS = False, False
        self.BRRIGHT, self.BRLEFT = False, False
        self.LEFTBUTTON, self.RIGHTBUTTON, self.SCROLL = False, False, False
        self.eyei = C.EYESTATES.index(eye)

        # Init Colors DW
        self.lastbrightness = self.brightness
        self.black = 0.0
        self.white = 1.0
示例#6
0
    def updateparams(self, i):
        """Updates stimulus parameters, given sweep table index i"""
        if i == None: # do a blank sweep
            self.gp.on = False # turn off the grating, leave all other parameters unchanged
            self.postval = C.MAXPOSTABLEINT # posted to DT port to indicate a blank sweep
            self.nvsyncs = sec2intvsync(self.blanksweeps.sec) # this many vsyncs for this sweep
            self.npostvsyncs = 0 # this many post-sweep vsyncs for this sweep, blank sweeps have no post-sweep delay
        else: # not a blank sweep
            self.gp.on = True # ensure grating is on
            self.postval = i # sweep table index will be posted to DT port
            self.nvsyncs = sec2intvsync(self.st.sweepSec[i]) # this many vsyncs for this sweep
            self.npostvsyncs = sec2intvsync(self.st.postsweepSec[i]) # this many post-sweep vsyncs for this sweep

            """Generate phase as a f'n of vsynci for this sweep
            sine grating eq'n used by VE: luminance(x) = 0.5*contrast*sin(2*pi*sfreqCycDeg*x + phaseRad) + ml ...where x is the position in deg along the axis of the sinusoid, and phaseRad = phaseDeg/180*pi. Motion in time is achieved by changing phaseDeg over time. phaseDeg inits to phase0"""
            sfreq = cycDeg2cycPix(self.st.sfreqCycDeg[i]) # convert it just once, reuse it for this sweep
            """phaseoffset is req'd to make phase0 the initial phase at the centre of the grating, instead of at the edge of the grating as VE does. Take the distance from the centre to the edge along the axis of the sinusoid (which in this case is the height), multiply by spatial freq to get numcycles between centre and edge, multiply by 360 deg per cycle to get req'd phaseoffset. THE EXTRA 180 DEG IS NECESSARY FOR SOME REASON, DON'T REALLY UNDERSTAND WHY, BUT IT WORKS!!!"""
            phaseoffset = self.height / 2 * sfreq * 360 + 180
            phasestep = cycSec2cycVsync(self.st.tfreqCycSec[i]) * 360 # delta cycles per vsync, in degrees of sinusoid

            self.phase = -self.st.phase0[i] - phaseoffset - phasestep * np.arange(self.nvsyncs) # array of phases for this sweep. -ve makes the grating move in +ve direction along sinusoidal axis, see sin eq'n above

            # Update grating stimulus
            self.gp.position = self.xorig+deg2pix(self.st.xposDeg[i]), self.yorig+deg2pix(self.st.yposDeg[i])
            self.gp.orientation = self.static.orioff + self.st.ori[i] + 90 # VE defines grating ori as direction of motion of grating, but we want it to be the orientation of the grating elements, so add 90 deg (this also makes grating ori def'n correspond to bar ori def'n). This means that width and height have to be swapped (done at creation of grating)
            if self.masks:
                self.gp.mask = self.masks[self.st.diameterDeg[i]]
            self.gp.spatial_freq = sfreq
            self.gp.pedestal = self.st.ml[i]
            
            if self.st.contrastreverse[i]: 
                contraststep = cycSec2cycVsync(self.st.cfreqCycSec[i])*self.st.contrast[i]*2
                self.contrast =self.st.contrast[i]*np.sin(contraststep * np.arange(self.nvsyncs))
            else: self.gp.contrast = self.st.contrast[i]

            # Update background parameters
            self.bgp.color = self.st.bgbrightness[i], self.st.bgbrightness[i], self.st.bgbrightness[i], 1.0
示例#7
0
 def __init__(self, script, params):
     self.script = script.replace('\\', C.SLASH).replace('.pyc', '.py') # Experiment script file name, with stuff cleaned up
     self.script = os.path.splitdrive(self.script)[-1] # strip the drive name from the start
     self.params = params
     self.params.check()
     for paramname, paramval in params.items():
         setattr(self, paramname, paramval) # bind all parameter names to self
     self.flashvsyncs = sec2intvsync(self.flashSec)
     eye = dc.get('Eye', 'open')
     # Init signals
     self.squarelock, self.brightenText = False, False
     self.UP, self.DOWN, self.LEFT, self.RIGHT = False, False, False, False
     self.PLUS, self.MINUS, self.BRLEFT, self.BRRIGHT = False, False, False, False
     self.LEFTBUTTON, self.RIGHTBUTTON, self.SCROLL = False, False, False
     self.eyei = C.EYESTATES.index(eye)
     
     #Set up initial terrain
     self.brightness = self.terrain.color
     self.ori = self.terrain.orientation
     self.laps = []
     
     #Set up initial gratings
     self.gratingWidth = I.SCREENWIDTH*2
     self.gratingHeight = I.SCREENHEIGHT*2
     self.ml = 0.5
     self.snapDeg = 18
     
     #set up encoder
     self.encoder.start()
     time.sleep(0.2) #give NIDAQ chance to take a buffer of data
     self.encDeg = self.encoder.getDegrees()
     self.lastDx = 0
     if self.encoder.getVin() < 1:
         print 'Encoder not connected or powered on.'
     
     #set up reward
     self.reward.start()
     self.framescorrect = 0
     self.rewards = []
     
     #set up session clock
     self.sc = SessionClock()
     
     #set up logs
     self.posx = []
     self.dx = []
     self.terrainlog = []
示例#8
0
 def get_brightness(self):
     """Get target brightness"""
     if self.PLUS:
         self.brightness += self.brightnessstep
     elif self.MINUS:
         self.brightness -= self.brightnessstep
     self.brightness = max(self.brightness, 0)  # keep it >= 0
     self.brightness = min(self.brightness, 1)  # keep it <= 1
     """Set flash speed"""  # DW AIBS
     if self.BRRIGHT:
         self.flashSec += self.flashSecStep
     elif self.BRLEFT:
         self.flashSec -= self.flashSecStep
         self.flashSec = max(self.flashSec, 0)
     if self.flashSec == 0:
         self.flash = False
         self.tp.on = True  # toggle it
         self.tipp.on = True
     else:
         self.flash = True
     self.flashvsyncs = sec2intvsync(self.flashSec)
     self.flashvsyncs = intround(
         self.flashvsyncs / self.nscreens
     )  # normalize by number of screens to flip in each loop in main()
示例#9
0
    def run(self):
        """Run the experiment"""

        # Check it first
        self.check()

        info('Running Experiment script: %s' % self.script)

        # Build the SweepTable and the Header
        self.build()

        self.setgamma(self.static.gamma)

        # Init OpenGL graphics screen
        self.screen = ve.Core.get_default_screen()

        # Create VisionEgg stimuli objects, defined by each specific subclass of Experiment
        self.createstimuli()

        # Create a VisionEgg Viewport
        self.viewport = ve.Core.Viewport(screen=self.screen, stimuli=self.stimuli)

        self.initbackgroundcolor()

        self.fix1stsweeplag() # 1st sweep lag hacks

        # Create the VsyncTimer
        self.vsynctimer = Core.VsyncTimer()

        # Prepare IODAQ
        try:
            self.dOut = DigitalOutput('Dev1')  # device should be read from a config file
            self.dOut.StartTask()
            self.ni = True
        except:
            self.ni = False
            print "NIDAQ could not be initialized! No frame/sweep data will be output."

        self.sweepBit = 0
        self.frameBit = 1
        
        # Events (quit/pause etc)
        self.quit = False # init quit signal
        self.pause = False # init pause signal
        self.paused = False # remembers whether this experiment has been paused
        self.nvsyncsdisplayed = 0 # nvsyncs seen by Surf

        # time-critical stuff starts here
        self.sync2vsync(nswaps=2) # sync up to vsync signal, ensures that all following swap_buffers+glFlush call pairs return on the vsync

        self.startdatetime = datetime.datetime.now()
        self.starttime = time.clock() # precision timestamp

        # Do pre-experiment delay
        self.staticscreen(nvsyncs=sec2intvsync(self.static.preexpSec))

        # Run the main stimulus loop, defined by each specific subclass of Experiment
        self.main()

        # Do post-experiment delay
        self.staticscreen(nvsyncs=sec2intvsync(self.static.postexpSec))

        self.stoptime = time.clock() # precision timestamp
        self.stopdatetime = datetime.datetime.now()
        # time-critical stuff ends here

        if self.ni:
            self.dOut.WriteBit(self.sweepBit, 0) #ensure sweep bit is low
            self.dOut.WriteBit(self.frameBit, 0) #ensure frame bit is low
            self.dOut.ClearTask() #clear NIDAQ
        
        # Close OpenGL graphics screen (necessary when running from Python interpreter)
        self.screen.close()

        # Print messages to VisionEgg log and to screen
        info(self.vsynctimer.pprint())
        info('%d vsyncs displayed, %d sweeps completed' % (self.nvsyncsdisplayed, self.ii))
        info('Experiment duration: %s expected, %s actual' % (isotime(self.sec, 6), isotime(self.stoptime-self.starttime, 6)))
        if self.paused:
            warning('dimstim was paused at some point')
        if self.quit:
            warning('dimstim was interrupted before completion')
        else:
            info('dimstim completed successfully\n')
        printf2log('SWEEP ORDER: \n' + str(self.sweeptable.i.tolist()) + '\n')
        printf2log('SWEEP TABLE: \n' + self.sweeptable._pprint(None) + '\n')
        printf2log('\n' + '-'*80 + '\n') # add minuses to end of log to space it out between sessions
        
        # Log relevent objects to file.
        self.logmeta()
示例#10
0
    def run(self):
        """Run the experiment"""

        # Check it first
        self.check()

        info('Running Experiment script: %s' % self.script)

        # Build the SweepTable and the Header
        self.build()

        self.setgamma(self.static.gamma)

        # Init OpenGL graphics screen
        self.screen = ve.Core.get_default_screen()

        # Create VisionEgg stimuli objects, defined by each specific subclass of Experiment
        self.createstimuli()

        # Create a VisionEgg Viewport
        self.viewport = ve.Core.Viewport(screen=self.screen, stimuli=self.stimuli)

        self.initbackgroundcolor()

        self.fix1stsweeplag() # 1st sweep lag hacks

        # Create the VsyncTimer
        self.vsynctimer = Core.VsyncTimer()
        
        self.quit = False # init quit signal
        self.pause = False # init pause signal
        self.paused = False # remembers whether this experiment has been paused
        self.nvsyncsdisplayed = 0 # nvsyncs seen by Surf

        # time-critical stuff starts here
        self.sync2vsync(nswaps=2) # sync up to vsync signal, ensures that all following swap_buffers+glFlush call pairs return on the vsync

        self.startdatetime = datetime.datetime.now()
        self.starttime = time.clock() # precision timestamp

        # Do pre-experiment delay
        self.staticscreen(nvsyncs=sec2intvsync(self.static.preexpSec))

        # Run the main stimulus loop, defined by each specific subclass of Experiment
        self.main()

        # Do post-experiment delay
        self.staticscreen(nvsyncs=sec2intvsync(self.static.postexpSec))

        self.stoptime = time.clock() # precision timestamp
        self.stopdatetime = datetime.datetime.now()
        # time-critical stuff ends here
        
        # Close OpenGL graphics screen (necessary when running from Python interpreter)
        self.screen.close()

        # Print messages to VisionEgg log and to screen
        info(self.vsynctimer.pprint())
        info('%d vsyncs displayed, %d sweeps completed' % (self.nvsyncsdisplayed, self.ii))
        info('Experiment duration: %s expected, %s actual' % (isotime(self.sec, 6), isotime(self.stoptime-self.starttime, 6)))
        
        print "Logging Data..."
        self.logmeta()
        print "Logging Completed."