示例#1
0
def computeChaosPos(dir=0):
    if dir == -1:  # left
        directionRange1 = [-180, -20]
        directionRange2 = [20, 180]
    elif dir == 1:  # right
        directionRange1 = [-160, 0]
        directionRange2 = [0, 160]

    # Initial parameters
    dotsTheta = np.random.rand(nDots) * 360  # deg
    dotsRadius = (np.random.rand(nDots) ** 0.5) * fieldRadius  # in deg
    dotsX, dotsY = pol2cart(dotsTheta, dotsRadius)  # in deg
    XYpos = np.empty((nDots, 2, maxFrames))
    for iFrame in range(maxFrames):
        # choose direction
        dir1 = np.random.rand(int(nDots / 2)) * (directionRange1[1] - directionRange1[0]) + directionRange1[0]
        dir2 = np.random.rand(int(nDots / 2)) * (directionRange2[1] - directionRange2[0]) + directionRange2[0]
        dirAll = np.hstack((dir1, dir2))
        # update position
        dotsX, dotsY = dotsX + speedFrame * np.cos(dirAll), dotsY + speedFrame * np.sin(dirAll)
        # convert catesian to polar
        dotsTheta, dotsRadius = cart2pol(dotsX, dotsY)
        outFieldDots = (dotsRadius > fieldRadius)  # judge dots outside
        if outFieldDots.any():
            dotsRadius[outFieldDots] = np.random.rand(sum(outFieldDots)) * fieldRadius
            dotsTheta[outFieldDots] = np.random.rand(sum(outFieldDots)) * 360  # deg
        dotsX, dotsY = pol2cart(dotsTheta, dotsRadius)
        XYpos[:, 0, iFrame] = dotsX
        XYpos[:, 1, iFrame] = dotsY

    return XYpos
示例#2
0
 def get_flank_gap_pos(self, flank_orientation, flank_distance, num_flank,
                       target_orientation, gap):
     pos = pol2cart(-flank_orientation + 90,
                    0.5 * self.target_diameter + 0.5 * self.flank_height,
                    units='deg')
     pos = (pos[0] + self.eccentricity, pos[1])
     return pos
示例#3
0
    def test_element_array(self):
        win = self.win
        if not win._haveShaders:
            pytest.skip(
                "ElementArray requires shaders, which aren't available")
        #using init
        thetas = numpy.arange(0, 360, 10)
        N = len(thetas)

        radii = numpy.linspace(0, 1.0, N) * self.scaleFactor
        x, y = pol2cart(theta=thetas, radius=radii)
        xys = numpy.array([x, y]).transpose()
        spiral = visual.ElementArrayStim(win,
                                         opacities=0,
                                         nElements=N,
                                         sizes=0.5 * self.scaleFactor,
                                         sfs=1.0,
                                         xys=xys,
                                         oris=-thetas)
        spiral.draw()
        #check that the update function is working by changing vals after first draw() call
        spiral.opacities = 1.0
        spiral.sfs = 3.0
        spiral.draw()
        str(spiral)  #check that str(xxx) is working
        win.flip()
        spiral.draw()
        utils.compareScreenshot('elarray1_%s.png' % (self.contextName), win)
        win.flip()
示例#4
0
def dots_update(dotsX,
                dotsY,
                frameCount,
                dotSpeed=dotSpeed,
                frameDeathAfter=np.inf):
    # convert to polar coordinates
    dotsTheta, dotsRadius = cart2pol(dotsX, dotsY)
    # update radius
    dotsRadius = (dotsRadius + dotSpeed)
    # decide which dots die
    lgcOutFieldDots = np.zeros(len(dotsTheta), dtype='bool')
    if dotSpeed > 0:
        # create lgc for elems where radius too large
        lgcOutFieldDots = (dotsRadius >= FieldSizeRadius)
    elif dotSpeed < 0:
        # create lgc for elems where radius too small
        lgcOutFieldDots = (dotsRadius <= innerBorder)
    # create logical for where frameCount too high
    lgcFrameDeath = (frameCount >= frameDeathAfter)
    # combine logicals
    lgcDeath = np.logical_or(lgcOutFieldDots, lgcFrameDeath)
    # replace dead dots
    dotsRadius[lgcDeath] = np.random.uniform(innerBorder,
                                             FieldSizeRadius,
                                             size=sum(lgcDeath))
    dotsTheta[lgcDeath] = np.random.rand(sum(lgcDeath)) * 360
    # convert
    dotsX, dotsY = pol2cart(dotsTheta, dotsRadius)
    # increase frameCount for every elements
    frameCount += 1
    # set the counter for newborn dots to zero
    frameCount[lgcDeath] = 0
    return dotsX, dotsY, frameCount
示例#5
0
 def get_target_gap_pos_rect2(self, flank_orientation, flank_distance,
                              num_flank, target_orientation, gap):
     pos = pol2cart(-target_orientation + 90,
                    0.5 * self.target_diameter - 0.5 * self.line_width,
                    units='deg')
     pos = (pos[0] + self.eccentricity, pos[1])
     return pos
示例#6
0
def dots_init(nDots):
    # specify the angle for each dot
    dotsTheta = np.random.rand(nDots) * 360
    # specify the distance to the centre
    dotsRadius = (np.random.rand(nDots)**0.5) * FieldSizeRadius
    # convert
    dotsX, dotsY = pol2cart(dotsTheta, dotsRadius)
    return dotsX, dotsY
示例#7
0
def dots_init(nDots):
    # specify the angle for each dot
    dotsTheta = np.random.rand(nDots) * 360
    # specify the distance to the centre
    dotsRadius = (np.random.rand(nDots)**0.5) * FieldSizeRadius
    # convert
    dotsX, dotsY = pol2cart(dotsTheta, dotsRadius)
    # create array frameCount
    frameCount = np.random.uniform(0, dotLife, size=len(dotsX)).astype(int)
    return dotsX, dotsY, frameCount
示例#8
0
 def get_target_gap_pos(self,
                        flank_orientation=0,
                        flank_distance=0,
                        num_flank=0,
                        target_orientation=0,
                        gap=0,
                        offset=0):
     pos = pol2cart(-target_orientation + 90,
                    0.5 * self.target_diameter - 0.5 * self.line_width,
                    units='deg')
     pos = (pos[0] + self.eccentricity, pos[1])
     return pos
示例#9
0
def dots_update_inward(dotsXin, dotsYin):
    # convert to polar coordinates
    dotsTheta, dotsRadius = cart2pol(dotsXin, dotsYin)
    # update radius
    dotsRadius = (dotsRadius - dotSpeed)
    # random radius where radius too large
    outFieldDots = (dotsRadius <= 0)
    dotsRadius[outFieldDots] = (np.random.rand(sum(outFieldDots))**
                                0.5) * FieldSizeRadius
    # convert
    dotsXin, dotsYin = pol2cart(dotsTheta, dotsRadius)
    return dotsXin, dotsYin
示例#10
0
def dots_update_outward(dotsXout, dotsYout):
    # convert to polar coordinates
    dotsTheta, dotsRadius = cart2pol(dotsXout, dotsYout)
    #update radius
    dotsRadius = (dotsRadius + dotSpeed)
    #random radius where radius too large
    outFieldDots = (dotsRadius >= FieldSizeRadius)
    dotsRadius[outFieldDots] = np.random.rand(
        sum(outFieldDots)) * FieldSizeRadius
    # convert
    dotsXout, dotsYout = pol2cart(dotsTheta, dotsRadius)
    return dotsXout, dotsYout
示例#11
0
def dots_update_lifetime(dotsX,
                         dotsY,
                         frameCount,
                         dotSpeed=dotSpeed,
                         frameDeathAfter=np.inf):
    # convert to polar coordinates
    dotsTheta, dotsRadius = cart2pol(dotsX, dotsY)
    # update radius
    dotsRadius = (dotsRadius + dotSpeed)
    # update frameCount
    frameCount += 1
    # prepare array for dots that will die from falling out
    lgcOutFieldDots = np.zeros(len(dotsTheta), dtype='bool')

    # decide which dots fall out during expansion
    if dotSpeed > 0:
        # create lgc for elems where radius too large (expansion)
        lgcOutFieldDots = (dotsRadius >= FieldSizeRadius)
    # decide which dots fall out during contraction
    elif dotSpeed < 0:
        # create lgc for elems where radius too small (contraction)
        lgcOutFieldDots = (dotsRadius <= innerBorder)

    # decide which dots will die because they got too old
    lgcFrameDeath = (frameCount >= frameDeathAfter)
    # combine logicals from dots that died due to fell out and high age
    lgcDeath = np.logical_or(lgcOutFieldDots, lgcFrameDeath)

    radiOffset.append(dotsRadius[lgcDeath])

    # calculate new radius for dots that died
    dotsRadius[lgcDeath] = np.sqrt(
        (np.square(FieldSizeRadius) - np.square(innerBorder)) *
        np.random.rand(sum(lgcDeath)) + np.square(innerBorder))

    radiOnset.append(dotsRadius[lgcDeath])

    # calculate new angle for all dots that died (from age or falling)
    dotsTheta[lgcDeath] = np.random.uniform(0, 360, sum(lgcDeath))

    # reset the counter for newborn dots that died of high age
    frameCount[lgcFrameDeath] = 0
    # reset the counter for newborn dots that died from falling out
    frameCount[lgcOutFieldDots] = np.random.uniform(
        0, dotLife, size=sum(lgcOutFieldDots)).astype(int)

    radiDensity.append(dotsRadius)

    # convert from polar to Cartesian
    dotsX, dotsY = pol2cart(dotsTheta, dotsRadius)

    return dotsX, dotsY, frameCount
示例#12
0
def replot_out_dots( radius, thetaRads, X, Y, params ):
        
    # Determine who's out of range
    if ( params['displayRegion'] == 'ring' ):
        outField = (radius >= params['outerRadiusUnits'])
        inField = (radius <= 0)
        out = outField + inField
    elif ( params['displayRegion'] == 'rect' ):
        gtMaxX = (X >= params['maxXunits'])
        ltMinX = (X <= params['minXunits'])
        gtMaxY = (Y >= params['maxYunits'])
        ltMinY = (Y >= params['minYunits'])
        outX = ( gtMaxX | ltMinX )
        outY = ( gtMaxY | gtMaxY )
        out = ( outX | outY )
    else:
        print "Invalid displayRegion"
   
    if params['debugMode']:
        print 'Out= ' + str( sum( outField ) ) + '| In= ' + str( sum( inField ) )+ ' | MaxX = ' + str( numpy.max( X ) )  + ' | MinX = ' + str( numpy.min( X ) ) + ' | MinR = ' + str( numpy.min(radius) ) 
        
    # Replot based on replotMode and moveMode
    if params['replotMode'] == 'wrap':
        if params['displayRegion'] == 'ring':
            if (params['moveMode'] == 'radial') or (params['moveMode'] == 'rotation') or (params['moveMode'] == 'random'):
                if out.any:
                    radius = numpy.mod( radius, params['outerRadiusUnits']  )
                X, Y = pol2cart( thetaRads, radius, units='rads' )
            elif (params['moveMode'] == 'laminar'):
                if out.any: # mirror reverse X, Y coordinates
                    X[ out ] = -1.0*X[out]
                    Y[ out ] = -1.0*Y[out]
                thetaRads, radius = cart2pol( X, Y, units='rad' )
    elif params['replotMode'] == 'replot-scaled-polar':
        if outField.any:
                radius[outField], thetaRads[outField], X[outField], Y[outField] = make_dots( sum( outField ), params, min=0., max = params['innerRadiusUnits'], distributionMode = 'scaled-polar' )
        if inField.any:
            radius[inField], thetaRads[inField], X[inField], Y[inField] = make_dots( sum( inField ), params, min=params['outerRadiusUnits'], max=params['outerRadiusUnits']+params['dotSpeedUnits'], distributionMode = 'scaled-polar' )

    elif params['replotMode'] == 'replot-radial':
        if out.any:
            radius[out], thetaRads[out], X[out], Y[out] = make_dots( sum( out ), params, min=0, max=params['outerRadiusUnits'], distributionMode = 'uniform-polar' )

    elif params['replotMode'] == 'replot-rect':
        if out.any:
            radius[out], thetaRads[out], X[out], Y[out] = make_dots( sum( out ), params, min=params['xMinUnits'], max=params['xMaxUnits'], distributionMode='uniform-rect' )

        # Convert changed X,Y to polar
        thetaRads, radius = cart2pol( X, Y, units='rad' )
    # end if replotMode
    
    return radius, thetaRads, X, Y
示例#13
0
def dots_init(nDots):
    # initialise angle for each dot as a uniform distribution
    dotsTheta = np.random.uniform(0, 360, nDots)
    # initialise radius for each dot
    # in order to get an overall uniform distribution, the radius must not be
    # picked from a uniform distribution, but as pdf_r = (2/R^2)*r
    dotsRadius = np.sqrt((np.square(FieldSizeRadius) -
                          np.square(innerBorder)) * np.random.rand(nDots) +
                         np.square(innerBorder))
    # convert from polar to Cartesian
    dotsX, dotsY = pol2cart(dotsTheta, dotsRadius)
    # create array frameCount
    frameCount = np.random.uniform(0, dotLife, size=len(dotsX)).astype(int)
    return dotsX, dotsY, frameCount
示例#14
0
def make_dots( nDots, params, min=-1, max=1, distributionMode='uniform-rect' ):
    if distributionMode == 'scaled-polar':      # Adjusts for density change due to outward radial motion
        r = numpy.random.rand(nDots)**(0.5)*(max - min) + min
        th = numpy.random.rand(nDots)*(2*numpy.pi)-numpy.pi
        X, Y = pol2cart( th, r, units='rad' )
    elif distributionMode == 'uniform-polar':
        r = numpy.random.rand(nDots)*(max - min) + min
        th = numpy.random.rand(nDots)*(2*numpy.pi)-numpy.pi
        X, Y = pol2cart( th, r, units='rad' )
    elif distributionMode == 'fixed-circle':
        th = numpy.random.rand(nDots)*(2*numpy.pi)-numpy.pi
        r = numpy.ones(nDots)*.95
        X, Y = pol2cart( th, r, units='rad' )
    elif distributionMode == 'hybrid-uniform-rect-polar': # dots of uniform density in circular region
        X, Y = numpy.random.rand(nDots)*(max-min)+min, numpy.random.rand(nDots)*(max-min)+min
        th, r = cart2pol( X, Y, units = 'rad' )
        outR = ( r >= params['outerRadiusUnits'] )
        r[ outR ] = numpy.random.rand(sum(outR))*params['outerRadiusUnits']
        X, Y = pol2cart( th, r, units='rad' )
    else : # default is random in [-1,1] and [-1,1] in Cartesian coordinates
        X, Y = numpy.random.rand( nDots )*(max - min) + min, numpy.random.rand( nDots )*(max - min) + min
        th, r = cart2pol( X, Y, units = 'rad' )
        
    return r, th, X, Y
示例#15
0
 def test_element_array(self):
     win = self.win
     if not win._haveShaders or utils._under_xvfb:
         pytest.skip("ElementArray requires shaders, which aren't available")
     #using init
     thetas = numpy.arange(0,360,10)
     N=len(thetas)
     radii = numpy.linspace(0,1.0,N)*self.scaleFactor
     x, y = pol2cart(theta=thetas, radius=radii)
     xys = numpy.array([x,y]).transpose()
     spiral = visual.ElementArrayStim(win, nElements=N,sizes=0.5*self.scaleFactor,
         sfs=3.0, xys=xys, oris=thetas)
     spiral.draw()
     win.flip()
     spiral.draw()
     utils.compareScreenshot('elarray1_%s.png' %(self.contextName), win)
     win.flip()
示例#16
0
    def update_cal_target(self):
        ''' make sure target stimuli is already memory when being used by draw_cal_target '''

        if self.calTarget is 'picture':
            if self.pictureTargetFile is None:
                print(
                    'ERROR: Clibration target is None, please provide a picture'
                )
                core.quit()
            else:
                self.calibTar = visual.ImageStim(self.display,
                                                 self.pictureTargetFile,
                                                 size=self.targetSize)

        elif self.calTarget is 'spiral':
            thetas = numpy.arange(0, 1440, 10)
            N = len(thetas)
            radii = numpy.linspace(0, 1.0, N) * self.targetSize
            x, y = pol2cart(theta=thetas, radius=radii)
            xys = numpy.array([x, y]).transpose()
            self.calibTar = visual.ElementArrayStim(self.display,
                                                    nElements=N,
                                                    sizes=self.targetSize,
                                                    sfs=3.0,
                                                    xys=xys,
                                                    oris=-thetas)
        elif self.calTarget is 'movie':
            if self.movieTargetFile is None:
                print(
                    'ERROR: Clibration target is None, please provide a movie clip'
                )
                core.quit()
            else:
                self.calibTar = visual.MovieStim3(self.display,
                                                  self.movieTargetFile,
                                                  loop=True,
                                                  size=self.targetSize)

        else:  #'use the default 'circle'
            self.calibTar = visual.Circle(self.display,
                                          radius=self.targetSize / 2,
                                          lineColor=self.foregroundColor,
                                          fillColor=self.backgroundColor,
                                          lineWidth=self.targetSize / 2.0,
                                          units='pix')
示例#17
0
    def test_element_array(self):
        win = self.win
        if not win._haveShaders:
            pytest.skip("ElementArray requires shaders, which aren't available")
        #using init
        thetas = numpy.arange(0,360,10)
        N=len(thetas)

        radii = numpy.linspace(0,1.0,N)*self.scaleFactor
        x, y = pol2cart(theta=thetas, radius=radii)
        xys = numpy.array([x,y]).transpose()
        spiral = visual.ElementArrayStim(win, opacities = 0, nElements=N,sizes=0.5*self.scaleFactor,
            sfs=1.0, xys=xys, oris=-thetas)
        spiral.draw()
        #check that the update function is working by changing vals after first draw() call
        spiral.opacities = 1.0
        spiral.sfs = 3.0
        spiral.draw()
        str(spiral) #check that str(xxx) is working
        win.flip()
        spiral.draw()
        utils.compareScreenshot('elarray1_%s.png' %(self.contextName), win)
        win.flip()
示例#18
0
def move_dots( r, th, X, Y, params ):
    if params['moveMode'] == 'radial':
        # Coherent 
        r[ params['cohIndex'] ] += params['dotSpeedUnits']
        X[ params['cohIndex'] ], Y[ params['cohIndex'] ] = pol2cart(th[ params['cohIndex'] ], r[ params['cohIndex'] ], units='rad')

        # Incoherent
        if params['nDots'] > params['nCoherent']:
            inCohIndex = numpy.invert( params['cohIndex'] )
            dTheta = numpy.random.rand(params['nDots']-params['nCoherent'])*numpy.pi*2.0
            X[ inCohIndex ] += params['dotSpeedUnits']*numpy.cos( dTheta )
            Y[ inCohIndex ] += params['dotSpeedUnits']*numpy.sin( dTheta )
            th[ inCohIndex ], r[ inCohIndex ] = cart2pol( X[ inCohIndex ], Y[ inCohIndex ], units ='rad' )
        # Normalize Cartesian and Polar coordinates
        # X, Y = pol2cart(th, r, units='rad')
    elif params['moveMode'] == 'rotation-eq-angle':
        # Coherent
        th[ params['cohIndex'] ] += params['dotSpeedUnits']
        X[ params['cohIndex'] ], Y[ params['cohIndex'] ] = pol2cart(th[ params['cohIndex'] ], r[ params['cohIndex'] ], units='rad')
        
        # Incoherent
        if params['nDots'] > params['nCoherent']:
            inCohIndex = numpy.invert( params['cohIndex'] )
            dTheta = numpy.random.rand(params['nDots']-params['nCoherent'])*numpy.pi*2.0
            X[ inCohIndex ] += params['dotSpeedUnits']*numpy.cos( dTheta )
            Y[ inCohIndex ] += params['dotSpeedUnits']*numpy.sin( dTheta )
            th[ inCohIndex ], r[ inCohIndex ] = cart2pol( X[ inCohIndex ], Y[ inCohIndex ], units ='rad' )
            
    elif params['moveMode'] == 'rotation-eq-spd':
        # Coherent
        X[ params['cohIndex'] ] += params['dotSpeedUnits']*numpy.sin( numpy.pi - th[ params['cohIndex'] ] )
        Y[ params['cohIndex'] ] += params['dotSpeedUnits']*numpy.cos( numpy.pi - th[ params['cohIndex'] ] )
        th[ params['cohIndex'] ], r[ params['cohIndex'] ] = cart2pol( X[ params['cohIndex'] ], Y[ params['cohIndex'] ], units ='rad' )
        
        # Incoherent
        if params['nDots'] > params['nCoherent']:
            inCohIndex = numpy.invert( params['cohIndex'] )
            dTheta = numpy.random.rand(params['nDots']-params['nCoherent'])*numpy.pi*2.0
            X[ inCohIndex ] += params['dotSpeedUnits']*numpy.cos( dTheta )
            Y[ inCohIndex ] += params['dotSpeedUnits']*numpy.sin( dTheta )
            th[ inCohIndex ], r[ inCohIndex ] = cart2pol( X[ inCohIndex ], Y[ inCohIndex ], units ='rad' )

    elif params['moveMode'] == 'laminar':
        # Coherent
        X[ params['cohIndex'] ] += params['dotSpeedUnits']*numpy.cos( params['laminarDirRads'] )
        Y[ params['cohIndex'] ] += params['dotSpeedUnits']*numpy.sin( params['laminarDirRads'] )
        th[ params['cohIndex'] ], r[ params['cohIndex'] ] = cart2pol( X[ params['cohIndex'] ], Y[ params['cohIndex'] ], units ='rad' )
        
        # Incoherent
        if params['nDots'] > params['nCoherent']:
            inCohIndex = numpy.invert( params['cohIndex'] )
            dTheta = numpy.random.rand(params['nDots']-params['nCoherent'])*numpy.pi*2.0
            X[ inCohIndex ] += params['dotSpeedUnits']*numpy.cos( dTheta )
            Y[ inCohIndex ] += params['dotSpeedUnits']*numpy.sin( dTheta )
            th[ inCohIndex ], r[ inCohIndex ] = cart2pol( X[ inCohIndex ], Y[ inCohIndex ], units ='rad' )
       
    elif params['moveMode'] == 'random':
        dTheta = numpy.random.rand(params['nDots'])*numpy.pi*2.0
        X += params['dotSpeedUnits']*numpy.cos( dTheta )
        Y += params['dotSpeedUnits']*numpy.sin( dTheta )
        th, r = cart2pol( X, Y, units ='rad' )
    # end if moveMode
    
    return r, th, X, Y
maxSpeed = 10
# The size of the field. Note that you also need to modify the `fieldSize`
# keyword that is passed to `ElementArrayStim` below, due to (apparently) a bug
# in PsychoPy
fieldSize = 200
# The size of the dots
dotSize = 2
# The number of frames
nFrames = 1000

# Initial parameters
dotsTheta = numpy.random.rand(nDots)*360
dotsRadius = (numpy.random.rand(nDots)**0.5)*200
speed = numpy.random.rand(nDots)*maxSpeed

# Create the stimulus array
dots = visual.ElementArrayStim(window_handle, elementTex=None, fieldShape='circle',
                               elementMask='circle', nElements=nDots, sizes=dotSize,
                               units='pix', fieldSize=10000)

# Walk through each frame, update the dot positions and draw it
for frameN in range(100):
    # update radius
    dotsRadius = (dotsRadius+speed)
    # random radius where radius too large
    outFieldDots = (dotsRadius>=fieldSize)
    dotsRadius[outFieldDots] = numpy.random.rand(sum(outFieldDots))*fieldSize
    dotsX, dotsY = pol2cart(dotsTheta,dotsRadius)
    dots.setXYs(numpy.array([dotsX, dotsY]).transpose())
    dots.draw() 
    window_handle.flip()
示例#20
0
def dots_update_wrap(dotsX, dotsY, dotSpeed=dotSpeed):
    # convert to polar coordinates
    dotsTheta, dotsRadius = cart2pol(dotsX, dotsY)
    # update radius
    dotsRadius = (dotsRadius + dotSpeed)
    # prepare array for dots that will die from falling out
    lgcOutFieldDots = np.zeros(len(dotsTheta), dtype='bool')

    # decide which dots fall out during expansion
    if dotSpeed > 0:
        # create lgc for elems where radius too large (expansion)
        lgcOutFieldDots = (dotsRadius >= FieldSizeRadius)
        # how many dots should go in area A?
        numDotsAreaA = np.sum(
            np.random.choice(np.arange(2),
                             p=[1 - pAexp, pAexp],
                             size=np.sum(lgcOutFieldDots)))
        # get logical for area A
        lgcAdots = np.zeros(len(dotsTheta), dtype='bool')
        lgcAdots[np.where(lgcOutFieldDots)[0][:numDotsAreaA]] = True
        # calculate new radius for dots appearing in region A
        dotsRadius[lgcAdots] = innerBorder * np.sqrt(
            (np.square(alphaExp) - 1) * np.random.rand(sum(lgcAdots)) + 1)
        # get logical for area B
        lgcBdots = np.zeros(len(dotsTheta), dtype='bool')
        lgcBdots[np.where(lgcOutFieldDots)[0][numDotsAreaA:]] = True
        # calculate new radius for dots appearing in region B
        dotsRadius[lgcBdots] = np.sqrt(
            (np.square(FieldSizeRadius) - np.square(alphaExp) *
             np.square(innerBorder)) * np.random.rand(sum(lgcBdots)) +
            np.square(alphaExp) * np.square(innerBorder))

    # decide which dots fall out during contraction
    elif dotSpeed < 0:
        # create lgc for elems where radius too small (contraction)
        lgcOutFieldDots = (dotsRadius <= innerBorder)
        # how many dots should go in area A?
        numDotsAreaA = np.sum(
            np.random.choice(np.arange(2),
                             p=[1 - pAcontr, pAcontr],
                             size=np.sum(lgcOutFieldDots)))
        # get logical for area A
        lgcAdots = np.zeros(len(dotsTheta), dtype='bool')
        lgcAdots[np.where(lgcOutFieldDots)[0][:numDotsAreaA]] = True
        # calculate new radius for dots appearing in region A
        dotsRadius[lgcAdots] = Scontr * np.sqrt(
            (np.square(alphaContr) - 1) * np.random.rand(sum(lgcAdots)) + 1)
        # get logical for area B
        lgcBdots = np.zeros(len(dotsTheta), dtype='bool')
        lgcBdots[np.where(lgcOutFieldDots)[0][numDotsAreaA:]] = True
        # calculate new radius for dots appearing in region B
        dotsRadius[lgcBdots] = np.sqrt(
            (np.square(Scontr) - np.square(innerBorder)) *
            np.random.rand(sum(lgcBdots)) + np.square(innerBorder))

    # calculate new angle for all dots that died (from age or falling)
    dotsTheta[lgcOutFieldDots] = np.random.uniform(0, 360,
                                                   sum(lgcOutFieldDots))
    # convert from polar to Cartesian
    dotsX, dotsY = pol2cart(dotsTheta, dotsRadius)

    return dotsX, dotsY
def feedback_fn(block_n, condition, trial_n, trial_start, training=False):
    global training_score
    global bad_fb_onset_cnt
    surp = False

    # Check for responses
    if use_rtbox:
        (rts, btns) = rtbox.secs()
    else:
        responses = event.getKeys(keyList=[key], timeStamped=exp_clock)
        try:
            btns, rts = zip(
                *responses
            )  # unpack [(key1,time1),(key2,time2)] into (key1,key2) and (time1,time2)
        except ValueError:
            btns = []
            rts = []
    # Process responses
    if len(rts) > 0:
        if len(rts) > 1:  # Warning if more than one button was pressed
            win.logOnFlip(
                'WARNING!!! More than one response detected (taking first) on B{0}_T{1}: responses = {2}'
                .format(block_n, trial_n, rts), logging.WARNING)

        rt = rts[0] - trial_start  # take only first response
        btn = btns[0]
        error = rt - interval_dur
        error_angle = error * angle_ratio
        if not training and trial_n in surprise_trials[
                block_n]:  # Surprise on if not in training and if in list of surprise trials
            target_zone.setColor('blue')
            resp_marker.setLineColor(None)
            outcome_str = 'SURPRISE!'
            sound_file = select_surp_sound()
            surp = True
        elif np.abs(error) < tolerances[condition]:  # WIN
            target_zone.setColor('green')
            outcome_str = 'WIN!'
            sound_file = 'paradigm_sounds/{0}'.format(win_sound)
            win_flag = 0
        else:  # LOSS
            target_zone.setColor('red')
            outcome_str = 'LOSE!'
            sound_file = 'paradigm_sounds/{0}'.format(loss_sound)
            win_flag = 1
        resp_marker.setStart(
            pol2cart(error_angle + 270, loop_radius - resp_marker_width / 2))
        resp_marker.setEnd(
            pol2cart(error_angle + 270, loop_radius + resp_marker_width / 2))
    else:  # No response detected
        target_zone.setColor('red')
        outcome_str = 'None'
        rt = -1
        resp_marker.setLineColor(None)
        sound_file = 'paradigm_sounds/{0}'.format(loss_sound)
#        no_response_time = exp_clock.getTime()-trial_start
#        # Not adjusting tolerance for this type of trial...
    outcome_sound = sound.Sound(value=sound_file,
                                sampleRate=44100,
                                blockSize=block_sz,
                                secs=0.8,
                                stereo=1)
    outcome_sound.setVolume(0.8)

    # Present feedback
    #    preflip = exp_clock.getTime()-trial_start
    if paradigm_type == 'eeg':
        win.callOnFlip(port.setData, 2)
        sound_played = False
    else:
        win.callOnFlip(outcome_sound.play)
        sound_played = True

    for frameN in range(
            feedback_dur * 60
    ):  #assuming frame_rate is close enough it would round to 60 (this must be an int)
        if paradigm_type == 'ecog':
            trigger_rect.draw()
        target_zone_draw(
        )  # Using our defined target_zone_draw, not .draw to have correct visual.
        resp_marker.draw()
        # Wait until 1.5 frames before desired presentation time, then create fixed timing between this flip and sound/draw onsets
        if frameN == 0:
            #            prewait = exp_clock.getTime()-trial_start
            #            desired = interval_dur + feedback_delay - 0.5/frame_rate
            while exp_clock.getTime(
            ) < trial_start + interval_dur + feedback_delay - 0.5 / frame_rate:
                # Hard coded delay for EEG:
                if not sound_played and exp_clock.getTime(
                ) > trial_start + interval_dur + feedback_delay - 0.16:
                    outcome_sound.play()
                    sound_played = True
                core.wait(0.00002)
        win.flip()
        if frameN == 0:
            feedback_onset = exp_clock.getTime() - trial_start
#            if feedback_onset > 1.793 or feedback_onset < 1.792:
#                bad_fb_onset_cnt += 1
#                print '{0} --> B{1}T{2} times:\n\tpreflip    {3}\n\tprewait    {4}\n\tdesired    {5}\n\tfeedback = {6}'.format(
#                    bad_fb_onset_cnt,block_n,trial_n,preflip,prewait,desired,feedback_onset)
    win.flip()

    if not surp and outcome_str != 'None':
        tolerances[condition] += tolerance_step[condition][
            win_flag]  # Update tolerances based on feedback. Needs to be here.
        if tolerances[condition] > tolerance_lim[
                0]:  #!!! Won't work if moved to staircase. Would need new implementation.
            tolerances[condition] = tolerance_lim[0]
        elif tolerances[condition] < tolerance_lim[1]:
            tolerances[condition] = tolerance_lim[1]
        if training and trial_n >= n_fullvis:
            training_score[condition] += point_fn[win_flag]

        elif not training:
            points[block_n] += point_fn[win_flag]
    if training:
        win.logOnFlip(
            feedback_str.format('T', trial_n, outcome_str, rt, condition,
                                tolerances[condition]), logging.DATA)
        win.logOnFlip(
            'B{0}_T{1} responses/times = {2} / {3}'.format(
                'T', trial_n, btns, rts), logging.DATA)
        win.logOnFlip(
            'B{0}_T{1} SOUND = {2} feedback start: TIME = {3}'.format(
                'T', trial_n, sound_file, feedback_onset), logging.DATA)
    else:
        win.logOnFlip(
            feedback_str.format(block_n, trial_n, outcome_str, rt, condition,
                                tolerances[condition]), logging.DATA)
        win.logOnFlip(
            'B{0}_T{1} responses/times = {2} / {3}'.format(
                block_n, trial_n, btns, rts), logging.DATA)
        win.logOnFlip(
            'B{0}_T{1} SOUND = {2} feedback start: TIME = {3}'.format(
                block_n, trial_n, sound_file, feedback_onset), logging.DATA)
    resp_marker.setLineColor('black')
    target_zone.setColor('dimgrey')
    while exp_clock.getTime() < trial_start + trial_dur:
        for press in event.getKeys(keyList=['escape', 'q']):
            if press:
                clean_quit()
示例#22
0
else:
    block_szs = [512, 512]
sound_srate = 22050
stereo_val = 1
# Create a sound just so the stream gets initialized...
tmp_sound = sound.Sound(value=tar_name, sampleRate=sound_srate, blockSize=block_szs[0],
			 secs=stim_dur, stereo=stereo_val, volume=volumes[0])

#===================================================
#           VISUAL STIMULI
#===================================================
# "Light" Stimuli
#---------------------------------------------------
circ_angles = np.linspace(-90,270,n_circ) #np.array([float(pos_ix)*(360/float(n_circ))-90 for pos_ix in range(n_circ)])
circ_radius = [loop_radius] * n_circ
circ_X, circ_Y = pol2cart(circ_angles,circ_radius)
circ_start = [circ_ix * (1/float(n_circ)) for circ_ix in range(n_circ)]  # onset time of each light
hidden_pos = [(circ_start[circ_xi] > (1-covered_portion)) for circ_xi in range(n_circ)]

socket_colors = [(-1,-1,-1)] * n_circ          # Sets black circles
circ_colors = [(-1,-1,-1)] * (n_circ - sum(hidden_pos)) + [(0, 0, 0)] * sum(hidden_pos) # 13 black + 17 gray

circles = visual.ElementArrayStim(win, nElements=n_circ, sizes=circ_size, xys = zip(circ_X, circ_Y),       # Circle object inset ontop of sockets 
                           elementTex = None, elementMask = "circle",
                           colors=circ_colors)
sockets = visual.ElementArrayStim(win, nElements=n_circ,sizes=socket_size,xys = zip(circ_X, circ_Y),     # "Sockets" providing outter black ring for circles.
                           elementTex = None, elementMask = "circle",                                   # always present behind circle stim
                           colors=socket_colors)

#---------------------------------------------------
# Target Zone
    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 'picture':
            if self.pictureTargetFile is None:
                print(
                    'ERROR: Clibration target is None, please provide a picture'
                )
                core.quit()
            else:
                self.calibTar = visual.ImageStim(self.display,
                                                 self.pictureTargetFile,
                                                 size=self.targetSize)

        elif self.calTarget is 'spiral':
            thetas = numpy.arange(0, 1440, 10)
            N = len(thetas)
            radii = numpy.linspace(0, 1.0, N) * self.targetSize
            x, y = pol2cart(theta=thetas, radius=radii)
            xys = numpy.array([x, y]).transpose()
            self.calibTar = visual.ElementArrayStim(self.display,
                                                    nElements=N,
                                                    sizes=self.targetSize,
                                                    sfs=3.0,
                                                    xys=xys,
                                                    oris=-thetas)
        elif self.calTarget is 'movie':
            if self.movieTargetFile is None:
                print(
                    'ERROR: Clibration target is None, please provide a movie clip'
                )
                core.quit()
            else:
                self.calibTar = visual.MovieStim3(self.display,
                                                  self.movieTargetFile,
                                                  loop=True,
                                                  size=self.targetSize)

        else:  #'use the default 'circle'
            self.calibTar = visual.Circle(self.display,
                                          radius=self.targetSize / 2,
                                          lineColor=self.foregroundColor,
                                          fillColor=self.backgroundColor,
                                          lineWidth=self.targetSize / 2.,
                                          units='pix')

        # update the target position
        if self.calTarget is 'spiral':
            self.calibTar.fieldPos = (xVis, yVis)
        else:
            self.calibTar.pos = (xVis, yVis)

        # handle the drawing
        if self.calTarget in ['movie', 'spiral']:
            self.animatedTarget = True  # hand over drawing to get_input_key
        else:
            self.calibTar.draw()
            self.display.flip()
示例#24
0
    TargsQuad   = CondsTargetQuadrants[cond][subCond-1]
    DistracQuad = CondsDistraQuadrants[cond][subCond-1]

    trialTargPos = []
    targRadPos   = np.empty(4)
    targRadPos[:] =np.nan

    switch = np.random.random()>0.5
    for ii in range(nT):
        if (cond>3 and switch): ii = (nT-1) - ii
        qq = TargsQuad[ii] # target quadrant
        theta = np.random.choice(PossibleObjTheta[qq-1], replace=False)
        radixID = int(np.random.random()>0.5)
        targRadPos[qq-1] = radixID
        radix = PossibleObjRadix[radixID]
        x,y = coord.pol2cart(theta, radix, units='deg')
        trialTargPos.append((x,y))

        if (TargetChangeID[tt]==-1) & (TrialChangeCondID[tt]<3):
            if (TrialChangeCondID[tt]==1) & (theta>90 and theta<270):
                TargetChangeID[tt]=ii
            elif (TrialChangeCondID[tt]==2) & (theta<90 or theta>270):
                TargetChangeID[tt]=ii

    trialDisPos = []
    for ii in range(nD):
        qq = DistracQuad[ii] # target quadrant
        theta = np.random.choice(PossibleObjTheta[qq-1], replace=False)
        if targRadPos[qq-1]==1:
            radix = PossibleObjRadix[0]
        elif targRadPos[qq-1]==0:
示例#25
0
 def init_trial_stimuli(self):
     self.trial_stimuli = {
         # Fixation stimulus indicating start of the trial
         'fixation':
         visual.ShapeStim(self.test_screen,
                          units=None,
                          lineWidth=4,
                          pos=[0, 0],
                          lineColor='white',
                          closeShape=False,
                          vertices=((0, -10), (0, 10), (0, 0), (-10, 0),
                                    (10, 0))),
         # Trial stimuli
         'blanc1':
         visual.Circle(self.test_screen,
                       units=None,
                       radius=50,
                       pos=pol2cart(15, 160, units='deg'),
                       lineWidth=5,
                       lineColor='white'),
         'blanc2':
         visual.Circle(self.test_screen,
                       units=None,
                       radius=50,
                       pos=pol2cart(-55, 160, units='deg'),
                       lineWidth=5,
                       lineColor='white'),
         'blanc3':
         visual.Circle(self.test_screen,
                       units=None,
                       radius=50,
                       pos=pol2cart(-125, 160, units='deg'),
                       lineWidth=5,
                       lineColor='white'),
         'blanc4':
         visual.Circle(self.test_screen,
                       units=None,
                       radius=50,
                       pos=pol2cart(-195, 160, units='deg'),
                       lineWidth=5,
                       lineColor='white'),
         'stim1':
         visual.Circle(self.test_screen,
                       units=None,
                       radius=25,
                       pos=pol2cart(15, 160, units='deg'),
                       lineWidth=3,
                       fillColor='white'),
         'stim2':
         visual.Circle(self.test_screen,
                       units=None,
                       radius=25,
                       pos=pol2cart(-55, 160, units='deg'),
                       lineWidth=3,
                       fillColor='white'),
         'stim3':
         visual.Circle(self.test_screen,
                       units=None,
                       radius=25,
                       pos=pol2cart(-125, 160, units='deg'),
                       lineWidth=3,
                       fillColor='white'),
         'stim4':
         visual.Circle(self.test_screen,
                       units=None,
                       radius=25,
                       pos=pol2cart(-195, 160, units='deg'),
                       lineWidth=3,
                       fillColor='white'),
         'hint_1':
         visual.TextStim(self.test_screen,
                         text='P',
                         pos=pol2cart(15, 160, units='deg'),
                         color='white',
                         height=30),
         'hint_2':
         visual.TextStim(self.test_screen,
                         text='L',
                         pos=pol2cart(-55, 160, units='deg'),
                         color='white',
                         height=30),
         'hint_3':
         visual.TextStim(self.test_screen,
                         text='D',
                         pos=pol2cart(-125, 160, units='deg'),
                         color='white',
                         height=30),
         'hint_4':
         visual.TextStim(self.test_screen,
                         text='E',
                         pos=pol2cart(-195, 160, units='deg'),
                         color='white',
                         height=30)
     }
示例#26
0
 def init_trial_stimuli(self):
     self.trial_stimuli = {
         # Fixation stimulus indicating start of the trial
         'fixation':
         visual.ShapeStim(self.test_screen,
                          units=None,
                          lineWidth=4,
                          pos=[0, 0],
                          lineColor='white',
                          closeShape=False,
                          vertices=((0, -10), (0, 10), (0, 0), (-10, 0),
                                    (10, 0))),
         # Trial stimuli
         'red': {
             'solid': {
                 'circle': [
                     visual.Circle(self.test_screen,
                                   units=None,
                                   radius=40,
                                   pos=[-130, 0],
                                   lineWidth=6,
                                   lineColor=self.colors['red'],
                                   fillColor=self.colors['red'],
                                   lineColorSpace='rgb255',
                                   fillColorSpace='rgb255'),
                     visual.Circle(self.test_screen,
                                   units=None,
                                   radius=40,
                                   pos=[130, 0],
                                   lineWidth=6,
                                   lineColor=self.colors['red'],
                                   fillColor=self.colors['red'],
                                   lineColorSpace='rgb255',
                                   fillColorSpace='rgb255')
                 ],
                 'triangle': [
                     visual.ShapeStim(self.test_screen,
                                      units=None,
                                      pos=[-130, -0.33 * 40],
                                      lineWidth=6,
                                      closeShape=True,
                                      vertices=(pol2cart(90,
                                                         1.17 * 40,
                                                         units='deg'),
                                                pol2cart(210,
                                                         1.17 * 40,
                                                         units='deg'),
                                                pol2cart(330,
                                                         1.17 * 40,
                                                         units='deg')),
                                      lineColor=self.colors['red'],
                                      fillColor=self.colors['red'],
                                      lineColorSpace='rgb255',
                                      fillColorSpace='rgb255'),
                     visual.ShapeStim(self.test_screen,
                                      units=None,
                                      pos=[130, -0.33 * 40],
                                      lineWidth=6,
                                      closeShape=True,
                                      vertices=(pol2cart(90,
                                                         1.17 * 40,
                                                         units='deg'),
                                                pol2cart(210,
                                                         1.17 * 40,
                                                         units='deg'),
                                                pol2cart(330,
                                                         1.17 * 40,
                                                         units='deg')),
                                      lineColor=self.colors['red'],
                                      fillColor=self.colors['red'],
                                      lineColorSpace='rgb255',
                                      fillColorSpace='rgb255')
                 ]
             },
             'contour': {
                 'circle': [
                     visual.Circle(self.test_screen,
                                   units=None,
                                   radius=40,
                                   pos=[-130, 0],
                                   lineWidth=6,
                                   lineColor=self.colors['red'],
                                   fillColor=None,
                                   lineColorSpace='rgb255',
                                   fillColorSpace='rgb255'),
                     visual.Circle(self.test_screen,
                                   units=None,
                                   radius=40,
                                   pos=[130, 0],
                                   lineWidth=6,
                                   lineColor=self.colors['red'],
                                   fillColor=None,
                                   lineColorSpace='rgb255',
                                   fillColorSpace='rgb255')
                 ],
                 'triangle': [
                     visual.ShapeStim(self.test_screen,
                                      units=None,
                                      pos=[-130, -0.33 * 40],
                                      lineWidth=6,
                                      closeShape=True,
                                      vertices=(pol2cart(90,
                                                         1.17 * 40,
                                                         units='deg'),
                                                pol2cart(210,
                                                         1.17 * 40,
                                                         units='deg'),
                                                pol2cart(330,
                                                         1.17 * 40,
                                                         units='deg')),
                                      lineColor=self.colors['red'],
                                      fillColor=None,
                                      lineColorSpace='rgb255',
                                      fillColorSpace='rgb255'),
                     visual.ShapeStim(self.test_screen,
                                      units=None,
                                      pos=[130, -0.33 * 40],
                                      lineWidth=6,
                                      closeShape=True,
                                      vertices=(pol2cart(90,
                                                         1.17 * 40,
                                                         units='deg'),
                                                pol2cart(210,
                                                         1.17 * 40,
                                                         units='deg'),
                                                pol2cart(330,
                                                         1.17 * 40,
                                                         units='deg')),
                                      lineColor=self.colors['red'],
                                      fillColor=None,
                                      lineColorSpace='rgb255',
                                      fillColorSpace='rgb255')
                 ]
             }
         },
         'green': {
             'solid': {
                 'circle': [
                     visual.Circle(self.test_screen,
                                   units=None,
                                   radius=40,
                                   pos=[-130, 0],
                                   lineWidth=6,
                                   lineColor=self.colors['green'],
                                   fillColor=self.colors['green'],
                                   lineColorSpace='rgb255',
                                   fillColorSpace='rgb255'),
                     visual.Circle(self.test_screen,
                                   units=None,
                                   radius=40,
                                   pos=[130, 0],
                                   lineWidth=6,
                                   lineColor=self.colors['green'],
                                   fillColor=self.colors['green'],
                                   lineColorSpace='rgb255',
                                   fillColorSpace='rgb255')
                 ],
                 'triangle': [
                     visual.ShapeStim(self.test_screen,
                                      units=None,
                                      pos=[-130, -0.33 * 40],
                                      lineWidth=6,
                                      closeShape=True,
                                      vertices=(pol2cart(90,
                                                         1.17 * 40,
                                                         units='deg'),
                                                pol2cart(210,
                                                         1.17 * 40,
                                                         units='deg'),
                                                pol2cart(330,
                                                         1.17 * 40,
                                                         units='deg')),
                                      lineColor=self.colors['green'],
                                      fillColor=self.colors['green'],
                                      lineColorSpace='rgb255',
                                      fillColorSpace='rgb255'),
                     visual.ShapeStim(self.test_screen,
                                      units=None,
                                      pos=[130, -0.33 * 40],
                                      lineWidth=6,
                                      closeShape=True,
                                      vertices=(pol2cart(90,
                                                         1.17 * 40,
                                                         units='deg'),
                                                pol2cart(210,
                                                         1.17 * 40,
                                                         units='deg'),
                                                pol2cart(330,
                                                         1.17 * 40,
                                                         units='deg')),
                                      lineColor=self.colors['green'],
                                      fillColor=self.colors['green'],
                                      lineColorSpace='rgb255',
                                      fillColorSpace='rgb255')
                 ]
             },
             'contour': {
                 'circle': [
                     visual.Circle(self.test_screen,
                                   units=None,
                                   radius=40,
                                   pos=[-130, 0],
                                   lineWidth=6,
                                   lineColor=self.colors['green'],
                                   fillColor=None,
                                   lineColorSpace='rgb255',
                                   fillColorSpace='rgb255'),
                     visual.Circle(self.test_screen,
                                   units=None,
                                   radius=40,
                                   pos=[130, 0],
                                   lineWidth=6,
                                   lineColor=self.colors['green'],
                                   fillColor=None,
                                   lineColorSpace='rgb255',
                                   fillColorSpace='rgb255')
                 ],
                 'triangle': [
                     visual.ShapeStim(self.test_screen,
                                      units=None,
                                      pos=[-130, -0.33 * 40],
                                      lineWidth=6,
                                      closeShape=True,
                                      vertices=(pol2cart(90,
                                                         1.17 * 40,
                                                         units='deg'),
                                                pol2cart(210,
                                                         1.17 * 40,
                                                         units='deg'),
                                                pol2cart(330,
                                                         1.17 * 40,
                                                         units='deg')),
                                      lineColor=self.colors['green'],
                                      fillColor=None,
                                      lineColorSpace='rgb255',
                                      fillColorSpace='rgb255'),
                     visual.ShapeStim(self.test_screen,
                                      units=None,
                                      pos=[130, -0.33 * 40],
                                      lineWidth=6,
                                      closeShape=True,
                                      vertices=(pol2cart(90,
                                                         1.17 * 40,
                                                         units='deg'),
                                                pol2cart(210,
                                                         1.17 * 40,
                                                         units='deg'),
                                                pol2cart(330,
                                                         1.17 * 40,
                                                         units='deg')),
                                      lineColor=self.colors['green'],
                                      fillColor=None,
                                      lineColorSpace='rgb255',
                                      fillColorSpace='rgb255')
                 ]
             }
         },
         'cue1':
         visual.TextStim(self.test_screen, text=u'ФОРМА'),
         'cue2':
         visual.TextStim(self.test_screen, text=u'ЦВЕТ'),
         'hint_D':
         visual.TextStim(self.test_screen,
                         text=u'D <- одинаковые',
                         height=25,
                         pos=[-330, 0],
                         color='white'),
         'hint_L':
         visual.TextStim(self.test_screen,
                         text=u'разные -> L',
                         height=25,
                         pos=[330, 0],
                         color='white')
     }
示例#27
0
dotSize = .0075

dotsTheta = numpy.random.rand(nDots) * 360
dotsRadius = (numpy.random.rand(nDots)**0.5) * 2
speed = numpy.random.rand(nDots) * maxSpeed

win = visual.Window([800, 600], rgb=[-1, -1, -1])
dots = visual.ElementArrayStim(win,
                               elementTex=None,
                               elementMask='circle',
                               nElements=nDots,
                               sizes=dotSize)

while True:
    #update radius
    dotsRadius = (dotsRadius + speed)
    #random radius where radius too large
    outFieldDots = (dotsRadius >= 2.0)
    dotsRadius[outFieldDots] = numpy.random.rand(sum(outFieldDots)) * 2.0

    dotsX, dotsY = pol2cart(dotsTheta, dotsRadius)
    dotsX *= 0.75  #to account for wider aspect ratio
    dots.xys = numpy.array([dotsX, dotsY]).transpose()
    dots.draw()

    win.flip()

    # Exit on escape
    if event.getKeys(keyList=['escape', 'q']):
        break
示例#28
0
文件: dot.py 项目: Beibaibaby/dot
def stimulus_chaos(direction):
    nDots = 50
    # The maximum speed of the dots
    maxSpeed = 10  # 10 is degree, should switch to pixels
    # The size of the field. Note that you also need to modify the `fieldSize`
    # keyword that is passed to `ElementArrayStim` below, due to (apparently) a bug
    # in PsychoPy
    fieldSize = 200
    # The size of the dots
    dotSize = 5
    # The number of frames
    nFrames = 1000
    # Initial parameters
    dotsTheta = np.random.rand(nDots) * 360
    dotsRadius = (np.random.rand(nDots)**0.5) * fieldSize
    dotsX, dotsY = pol2cart(dotsTheta, dotsRadius)
    speed = maxSpeed
    if direction == 1:  # left
        directionRange1 = [-180, -20]
        directionRange2 = [20, 180]
    elif direction == 2:  # right
        directionRange1 = [-160, 0]
        directionRange2 = [0, 160]

    # Create the stimulus array
    dots = visual.ElementArrayStim(myWin, elementTex=None, fieldShape='circle', \
                                   elementMask='circle', nElements=nDots, sizes=dotSize, units='pixels', \
                                   fieldSize=500)

    # Walk through each frame, update the dot positions and draw it
    dir1 = np.random.rand(int(nDots / 2)) * (
        directionRange1[1] - directionRange1[0]) + directionRange1[0]
    dir2 = np.random.rand(int(nDots / 2)) * (
        directionRange2[1] - directionRange2[0]) + directionRange2[0]

    dir = np.hstack((dir1, dir2))
    np.random.shuffle(dir)

    for frameN in range(5000):
        # draw random directions
        re = frameN % 10
        while re == 0:
            dir1 = np.random.rand(int(nDots / 2)) * (
                directionRange1[1] - directionRange1[0]) + directionRange1[0]
            dir2 = np.random.rand(int(nDots / 2)) * (
                directionRange2[1] - directionRange2[0]) + directionRange2[0]
            dir = np.hstack((dir1, dir2))

        # update position
        dotsX, dotsY = dotsX + speed * np.cos(dir), dotsY + speed * np.sin(dir)
        # convert catesian to polar
        dotsTheta, dotsRadius = cart2pol(dotsX, dotsY)
        # random radius where radius too large

        outFieldDots = (dotsRadius > fieldSize)
        dotsRadius[outFieldDots] = np.random.rand(
            sum(outFieldDots)) * fieldSize

        dotsX, dotsY = pol2cart(dotsTheta, dotsRadius)
        #坐标转换
        dots.setXYs(np.array([dotsX, dotsY]).transpose())
        dots.draw()
        myWin.flip()