Example #1
0
def dkl2rgb(dkl_Nx3, conversionMatrix=None):
    #Convert from DKL color space (cone-opponent space from Derrington,
    #Krauskopf & Lennie) to RGB. 

    #Requires a conversion matrix, which will be generated from generic
    #Sony Trinitron phosphors if not supplied (note that this will not be
    #an accurate representation of the color space unless you supply a 
    #conversion matrix
    #
    #usage:
        #rgb(Nx3) = dkl2rgb(dkl_Nx3(el,az,radius), conversionMatrix)
    
    dkl_3xN = numpy.transpose(dkl_Nx3)#its easier to use in the other orientation!
    if numpy.size(dkl_3xN)==3:
        RG, BY, LUM = sph2cart(dkl_3xN[0],dkl_3xN[1],dkl_3xN[2])
    else:
        RG, BY, LUM = sph2cart(dkl_3xN[0,:],dkl_3xN[1,:],dkl_3xN[2,:])
    dkl_cartesian = numpy.asarray([LUM, RG, BY])
    
    if conversionMatrix==None:
        conversionMatrix = numpy.asarray([ \
            #LUMIN    %L-M    %L+M-S  (note that dkl has to be in cartesian coords first!)
            [1.0000, 1.0000, -0.1462],#R
            [1.0000, -0.3900, 0.2094],#G
            [1.0000, 0.0180, -1.0000]])#B
        log.warning('This monitor has not been color-calibrated. Using default DKL conversion matrix.')
        
    rgb = numpy.dot(conversionMatrix, dkl_cartesian)
    
    return numpy.transpose(rgb)#return in the shape we received it
Example #2
0
def waitForVBL(screen=0, nFrames=1):
    """Wait for the given screen (typically screen is 0 or 1) to finish drawing before returning/
    If no screen is given then screen 0 is used.
    
    This is based on detecting the display beam position and may give unpredictable results for an LCD.
    """
    if importCtypesFailed: return False

    screens = getScreens()
    if screen > (len(screens) - 1):
        raise IndexError, "Requested refresh rate of screen %i, but only %i screens were found" % (
            screen, len(screens))
    else:
        scrID = getScreens()[screen]
    framePeriod = 1.0 / getRefreshRate(screen)
    if screen > 0:  #got multiple screens, check if they have same rate
        mainFramePeriod = 1.0 / getRefreshRate(0)
        if mainFramePeriod != framePeriod:
            #CGDisplayBeamPosition is unpredictable in this case - usually synced to the first monitor, but maybe better if 2 gfx cards?
            log.warning(
                "You are trying to wait for blanking on a secondary monitor that has a different \
refresh rate to your primary monitor. This is not recommended (likely to reduce your frame rate to the primary monitor)."
            )
    #when we're in a VBL the current beam position is greater than the screen height (for up to ~30 lines)
    top = getScreenSizePix(screen)[0]
    if cocoa.CGDisplayBeamPosition(scrID) > top:
        nFrames += 1  #we're in a VBL already, wait for one more
    while nFrames > 0:
        beamPos = cocoa.CGDisplayBeamPosition(scrID)  #get current pos
        #choose how long to wait
        while framePeriod * (
                top - beamPos
        ) / top > 0.005:  #we have at least 5ms to go so can wait for 1ms
            #            print 'plenty', beamPos, framePeriod*(top-beamPos)/top, time.time()
            #            time.sleep(0.0001)#actually it seems that time.sleep() waits too long on os x
            beamPos = cocoa.CGDisplayBeamPosition(scrID)  #get current pos
        #now near top so poll continuously
        while beamPos < top:
            beamPos = cocoa.CGDisplayBeamPosition(scrID)  #get current pos
        #if this was not the last frame, then wait until start of next frame before continuing
        #so that we don't detect the VBL again. If this was the last frame then get back to script asap
        if nFrames > 1:
            while beamPos >= top:
                beamPos = cocoa.CGDisplayBeamPosition(scrID)
        nFrames -= 1


#beamPos =  cocoa.CGDisplayBeamPosition(1)
#while beamPos<=1000:
#        beamPos =  cocoa.CGDisplayBeamPosition(1)
#        print beamPos
#first=last=time.time()
#print getRefreshRate(1)
#for nFrames in range(20):
#    waitForVBL(1, nFrames=1)
#    time.sleep(0.005)
#    this=time.time()
#    print this-first, this-last, 1/(this-last)
#    last=this
#rush()
Example #3
0
def rgb2dklCart(picture, conversionMatrix=None):
    """convert an RGB image into Cartesian DKL space"""
    #Turn the picture into an array so we can do maths
    picture=scipy.array(picture)
    #Find the original dimensions of the picture
    origShape = picture.shape

    #this is the inversion of the dkl2rgb conversion matrix
    if conversionMatrix==None:
        conversionMatrix = np.asarray([\
            #LUMIN->%L-M->L+M-S
            [ 0.25145542,  0.64933633,  0.09920825],
            [ 0.78737943, -0.55586618, -0.23151325],
            [ 0.26562825,  0.63933074, -0.90495899]])
        log.warning('This monitor has not been color-calibrated. Using default DKL conversion matrix.')
    else:
        conversionMatrix = np.linalg.inv(conversionMatrix)

    #Reshape the picture so that it can multiplied by the conversion matrix
    red = picture[:,:,0]
    green = picture[:,:,1]
    blue = picture[:,:,2]

    dkl = np.asarray([red.reshape([-1]), green.reshape([-1]), blue.reshape([-1])])
    
    #Multiply the picture by the conversion matrix
    dkl=np.dot(conversionMatrix, dkl)

    #Reshape the picture so that it's back to it's original shape
    dklPicture = np.reshape(np.transpose(dkl), origShape)
    return dklPicture
Example #4
0
def dkl2rgb(dkl_Nx3, conversionMatrix=None):
    #Convert from DKL color space (cone-opponent space from Derrington,
    #Krauskopf & Lennie) to RGB.

    #Requires a conversion matrix, which will be generated from generic
    #Sony Trinitron phosphors if not supplied (note that this will not be
    #an accurate representation of the color space unless you supply a
    #conversion matrix
    #
    #usage:
    #rgb(Nx3) = dkl2rgb(dkl_Nx3(el,az,radius), conversionMatrix)

    dkl_3xN = numpy.transpose(
        dkl_Nx3)  #its easier to use in the other orientation!
    if numpy.size(dkl_3xN) == 3:
        RG, BY, LUM = sph2cart(dkl_3xN[0], dkl_3xN[1], dkl_3xN[2])
    else:
        RG, BY, LUM = sph2cart(dkl_3xN[0, :], dkl_3xN[1, :], dkl_3xN[2, :])
    dkl_cartesian = numpy.asarray([LUM, RG, BY])

    if conversionMatrix == None:
        conversionMatrix = numpy.asarray([ \
            #LUMIN    %L-M    %L+M-S  (note that dkl has to be in cartesian coords first!)

            [1.0000, 1.0000, -0.1462],#R
            [1.0000, -0.3900, 0.2094],#G
            [1.0000, 0.0180, -1.0000]])#B
        log.warning(
            'This monitor has not been color-calibrated. Using default DKL conversion matrix.'
        )

    rgb = numpy.dot(conversionMatrix, dkl_cartesian)

    return numpy.transpose(rgb)  #return in the shape we received it
Example #5
0
def lms2rgb(lms_Nx3, conversionMatrix=None):
    #Convert from cone space (Long, Medium, Short) to RGB. 
    
    #Requires a conversion matrix, which will be generated from generic
    #Sony Trinitron phosphors if not supplied (note that you will not get
    #an accurate representation of the color space unless you supply a 
    #conversion matrix)
    #
    #usage:
        #rgb(Nx3) = lms2rgb(dkl_Nx3(el,az,radius), conversionMatrix)
    
    lms_3xN = numpy.transpose(lms_Nx3)#its easier to use in the other orientation!
        
    if conversionMatrix==None:
        cones_to_rgb = numpy.asarray([ \
            #L        M        S
            [ 4.97068857, -4.14354132, 0.17285275],#R
            [-0.90913894, 2.15671326, -0.24757432],#G
            [-0.03976551, -0.14253782, 1.18230333]#B
            ])
        log.warning('This monitor has not been color-calibrated. Using default LMS conversion matrix.')
    else: cones_to_rgb=conversionMatrix
    
    rgb_to_cones = numpy.linalg.pinv(cones_to_rgb)#get inverse
    rgb = numpy.dot(cones_to_rgb, lms_3xN)
    return numpy.transpose(rgb)#return in the shape we received it
Example #6
0
    def __init__(self,
                    win,
                    contrast=1.0,
                    gamma=[1.0,1.0,1.0],
                    nEntries=256,
                    bitsType='bits++',):
        self.win = win
        self.contrast=contrast
        self.nEntries=nEntries
        self.bitsType=bitsType
        self.method = 'fast'
        
        if len(gamma)>2: # [Lum,R,G,B] or [R,G,B]
            self.gamma=gamma[-3:]
        else:
            self.gamma = [gamma, gamma, gamma]
            
        if init(): 
            setVideoMode(NOGAMMACORRECT|VIDEOENCODEDCOMMS)
            self.initialised=True
            log.debug('found and initialised bits++')
        else: 
            self.initialised=False
            log.warning("couldn't initialise bits++")

        #do the processing
        self._HEADandLUT = numpy.zeros((524,1,3),numpy.uint8)
        self._HEADandLUT[:12,:,0] = numpy.asarray([ 36, 63, 8, 211, 3, 112, 56, 34,0,0,0,0]).reshape([12,1])#R
        self._HEADandLUT[:12,:,1] = numpy.asarray([ 106, 136, 19, 25, 115, 68, 41, 159,0,0,0,0]).reshape([12,1])#G
        self._HEADandLUT[:12,:,2] = numpy.asarray([ 133, 163, 138, 46, 164, 9, 49, 208,0,0,0,0]).reshape([12,1])#B
        self.LUT=numpy.zeros((256,3),'d')		#just a place holder
        self.setLUT()#this will set self.LUT and update self._LUTandHEAD
Example #7
0
def lms2rgb(lms_Nx3, conversionMatrix=None):
    #Convert from cone space (Long, Medium, Short) to RGB.

    #Requires a conversion matrix, which will be generated from generic
    #Sony Trinitron phosphors if not supplied (note that you will not get
    #an accurate representation of the color space unless you supply a
    #conversion matrix)
    #
    #usage:
    #rgb(Nx3) = lms2rgb(dkl_Nx3(el,az,radius), conversionMatrix)

    lms_3xN = numpy.transpose(
        lms_Nx3)  #its easier to use in the other orientation!

    if conversionMatrix == None:
        cones_to_rgb = numpy.asarray([ \
            #L        M        S

            [ 4.97068857, -4.14354132, 0.17285275],#R
            [-0.90913894, 2.15671326, -0.24757432],#G
            [-0.03976551, -0.14253782, 1.18230333]#B
            ])
        log.warning(
            'This monitor has not been color-calibrated. Using default LMS conversion matrix.'
        )
    else:
        cones_to_rgb = conversionMatrix

    rgb_to_cones = numpy.linalg.pinv(cones_to_rgb)  #get inverse
    rgb = numpy.dot(cones_to_rgb, lms_3xN)
    return numpy.transpose(rgb)  #return in the shape we received it
Example #8
0
def rush(value=True):    
    """Raise the priority of the current thread/process using 
        - sched_setscheduler
    
    NB for rush() to work on (debian-based?) linux requires that the script is run using a copy of python that
    is allowed to change priority, eg: sudo setcap cap_sys_nice=eip <sys.executable>, and maybe restart PsychoPy.
    If <sys.executable> is the system python, its important to restore it back to normal to avoid possible 
    side-effects. Alternatively, use a different python executable, and change its cap_sys_nice.
    
    For RedHat-based systems, 'sudo chrt ...' at run-time might be needed instead, not sure.
    see http://rt.et.redhat.com/wiki/images/8/8e/Rtprio.pdf
    """
    if importCtypesFailed: return False
    
    if value:#set to RR with max priority
        schedParams = _SchedParams()
        schedParams.sched_priority = c.sched_get_priority_max(SCHED_RR)
        err = c.sched_setscheduler(0,SCHED_RR, ctypes.byref(schedParams))
        if err==-1:#returns 0 if OK
            log.warning("""Failed to raise thread priority with sched_setscheduler.
To enable rush(), if you are using a debian-based linux, try this in a terminal window:
  'sudo setcap cap_sys_nice=eip %s'  [NB: You may need to install 'setcap' first.]
If you are using the system's python (eg /usr/bin/python2.x), its highly recommended
to change cap_sys_nice back to normal afterwards:
  'sudo setcap cap_sys_nice= %s'""" % (sys.executable,sys.executable))
    else:#set to RR with normal priority
        schedParams = _SchedParams()
        schedParams.sched_priority = c.sched_get_priority_min(SCHED_NORMAL)
        err = c.sched_setscheduler(0,SCHED_NORMAL, ctypes.byref(schedParams))
        if err==-1:#returns 0 if OK
            log.warning("""Failed to set thread priority back to normal level with sched_setscheduler.
Try:  'sudo setcap cap_sys_nice= %s'""" % (sys.executable))
    
    return True
Example #9
0
def gammaInvFun(yy, minLum, maxLum, gamma, b=None, eq=1):
    """Returns inverse gamma function for desired luminance values.
    x = gammaInvFun(y, minLum, maxLum, gamma)

    a and b are calculated directly from minLum, maxLum, gamma
    **Parameters:**

        - **xx** are the input values (range 0-255 or 0.0-1.0)
        - **minLum** = the minimum luminance of your monitor
        - **maxLum** = the maximum luminance of your monitor (for this gun)
        - **gamma** = the value of gamma (for this gun)
        - **eq** determines the gamma equation used;
            eq==1[default]: yy = a + (b*xx)**gamma
            eq==2: yy = (a + b*xx)**gamma

    """

    #x should be 0:1
    #y should be 0:1, then converted to minLum:maxLum

    #eq1: y = a + (b*xx)**gamma
    #eq2: y = (a+b*xx)**gamma
    #eq4: y = a+(b+kxx)**gamma
    if max(yy)==255:
        yy=numpy.asarray(yy)/255.0
    elif min(yy)<0 or max(yy)>1:
        log.warning('User supplied values outside the expected range (0:1)')

    #get into range minLum:maxLum
    yy = numpy.asarray(yy)*(maxLum - minLum) + minLum

    if eq==1:
        a = minLum
        b = (maxLum-a)**(1/gamma)
        xx = ((yy-a)**(1/gamma))/b
        minLUT = ((minLum-a)**(1/gamma))/b
        maxLUT = ((maxLum-a)**(1/gamma))/b
    elif eq==2:
        a = minLum**(1/gamma)
        b = maxLum**(1/gamma)-a
        xx = (yy**(1/gamma)-a)/b
        maxLUT = (maxLum**(1/gamma)-a)/b
        minLUT = (minLum**(1/gamma)-a)/b
    elif eq==3:#NB method 3 was an interpolation method that didn't work well
        pass
    elif eq==4:
        #this is not the same as Zhang and Pelli's inverse
        #see http://www.psychopy.org/general/gamma.html for derivation
        a = minLum-b**gamma
        k = (maxLum-a)**(1./gamma) - b
        xx = ((yy-a)**(1/gamma) - b)/k
        yy = (((1-xx)*b**gamma + xx*(b+k)**gamma)**(1/gamma)-b)/k
        maxLUT = ((maxLum-a)**(1/gamma) - b)/k
        minLUT = ((minLum-a)**(1/gamma) - b)/k
        #print "we are linearising with the special wichmann style equation"

    #then return to range (0:1)
    xx = xx/(maxLUT-minLUT) - minLUT
    return xx
Example #10
0
def gammaInvFun(yy, minLum, maxLum, gamma, b=None, eq=1):
    """Returns inverse gamma function for desired luminance values.
    x = gammaInvFun(y, minLum, maxLum, gamma)

    a and b are calculated directly from minLum, maxLum, gamma
    **Parameters:**

        - **xx** are the input values (range 0-255 or 0.0-1.0)
        - **minLum** = the minimum luminance of your monitor
        - **maxLum** = the maximum luminance of your monitor (for this gun)
        - **gamma** = the value of gamma (for this gun)
        - **eq** determines the gamma equation used;
            eq==1[default]: yy = a + (b*xx)**gamma
            eq==2: yy = (a + b*xx)**gamma

    """

    #x should be 0:1
    #y should be 0:1, then converted to minLum:maxLum

    #eq1: y = a + (b*xx)**gamma
    #eq2: y = (a+b*xx)**gamma
    #eq4: y = a+(b+kxx)**gamma
    if max(yy) == 255:
        yy = numpy.asarray(yy) / 255.0
    elif min(yy) < 0 or max(yy) > 1:
        log.warning('User supplied values outside the expected range (0:1)')

    #get into range minLum:maxLum
    yy = numpy.asarray(yy) * (maxLum - minLum) + minLum

    if eq == 1:
        a = minLum
        b = (maxLum - a)**(1 / gamma)
        xx = ((yy - a)**(1 / gamma)) / b
        minLUT = ((minLum - a)**(1 / gamma)) / b
        maxLUT = ((maxLum - a)**(1 / gamma)) / b
    elif eq == 2:
        a = minLum**(1 / gamma)
        b = maxLum**(1 / gamma) - a
        xx = (yy**(1 / gamma) - a) / b
        maxLUT = (maxLum**(1 / gamma) - a) / b
        minLUT = (minLum**(1 / gamma) - a) / b
    elif eq == 3:  #NB method 3 was an interpolation method that didn't work well
        pass
    elif eq == 4:
        #this is not the same as Zhang and Pelli's inverse
        #see http://www.psychopy.org/general/gamma.html for derivation
        a = minLum - b**gamma
        k = (maxLum - a)**(1. / gamma) - b
        xx = ((yy - a)**(1 / gamma) - b) / k
        yy = (((1 - xx) * b**gamma + xx * (b + k)**gamma)**(1 / gamma) - b) / k
        maxLUT = ((maxLum - a)**(1 / gamma) - b) / k
        minLUT = ((minLum - a)**(1 / gamma) - b) / k
        #print "we are linearising with the special wichmann style equation"

    #then return to range (0:1)
    xx = xx / (maxLUT - minLUT) - minLUT
    return xx
Example #11
0
def waitForVBL(screen=0,nFrames=1):
    """DEPRECATED: the code for doing this is now smaller and cross-platform so 
    is included in visual.Window.flip()
    
    This version is based on detecting the display beam position. It may give 
    unpredictable results for an LCD.
    """    
    if importCtypesFailed: return False
    
    screens=getScreens()
    if screen>(len(screens)-1):
        raise IndexError, "Requested refresh rate of screen %i, but only %i screens were found" %(screen, len(screens))
    else:
        scrID=getScreens()[screen]
    framePeriod=1.0/getRefreshRate(screen) 
    if screen>0: #got multiple screens, check if they have same rate
        mainFramePeriod = 1.0/getRefreshRate(0) 
        if mainFramePeriod!=framePeriod:
            #CGDisplayBeamPosition is unpredictable in this case - usually synced to the first monitor, but maybe better if 2 gfx cards?
            log.warning("You are trying to wait for blanking on a secondary monitor that has a different \
refresh rate to your primary monitor. This is not recommended (likely to reduce your frame rate to the primary monitor).")
    #when we're in a VBL the current beam position is greater than the screen height (for up to ~30 lines)
    top=getScreenSizePix(screen)[0]
    if cocoa.CGDisplayBeamPosition(scrID)>top:
        nFrames+=1#we're in a VBL already, wait for one more
    while nFrames>0:
        beamPos =  cocoa.CGDisplayBeamPosition(scrID)#get current pos
        #choose how long to wait
        while framePeriod*(top-beamPos)/top > 0.005:#we have at least 5ms to go so can wait for 1ms
#            print 'plenty', beamPos, framePeriod*(top-beamPos)/top, time.time()
#            time.sleep(0.0001)#actually it seems that time.sleep() waits too long on os x
            beamPos =  cocoa.CGDisplayBeamPosition(scrID)#get current pos
        #now near top so poll continuously
        while beamPos<top:
            beamPos =  cocoa.CGDisplayBeamPosition(scrID)#get current pos
        #if this was not the last frame, then wait until start of next frame before continuing
        #so that we don't detect the VBL again. If this was the last frame then get back to script asap
        if nFrames>1:
            while beamPos>=top:
                beamPos =  cocoa.CGDisplayBeamPosition(scrID)
        nFrames-=1
        
#beamPos =  cocoa.CGDisplayBeamPosition(1)
#while beamPos<=1000:
#        beamPos =  cocoa.CGDisplayBeamPosition(1)
#        print beamPos
#first=last=time.time()     
#print getRefreshRate(1)
#for nFrames in range(20):        
#    waitForVBL(1, nFrames=1) 
#    time.sleep(0.005)
#    this=time.time()
#    print this-first, this-last, 1/(this-last)
#    last=this
#rush()
Example #12
0
def sendUsageStats(proxy=None):
    """Sends anonymous, very basic usage stats to psychopy server:
      the version of PsychoPy
      the system used (platform and version)
      the date

    If http_proxy is set in the system environment variables these will be used automatically,
    but additional proxies can be provided here as the argument proxies.
    """
    v=psychopy.__version__
    dateNow = time.strftime("%Y-%m-%d_%H:%M")
    miscInfo = ''

    #urllib.install_opener(opener)
    #check for proxies
    if proxy in [None,""]:
        pass#use default opener (no proxies)
    else:
        #build the url opener with proxy and cookie handling
        opener = urllib2.build_opener(
            urllib2.ProxyHandler({'http':proxy}))
        urllib2.install_opener(opener)

    #get platform-specific info
    if sys.platform=='darwin':
        OSXver, junk, architecture = platform.mac_ver()
        systemInfo = "OSX_%s_%s" %(OSXver, architecture)
    elif sys.platform.startswith('linux'):
        systemInfo = '%s_%s_%s' % (
            'Linux',
            ':'.join([x for x in platform.dist() if x != '']),
            platform.release())
    elif sys.platform=='win32':
        ver=sys.getwindowsversion()
        if len(ver[4])>0:
            systemInfo=("win32_v%i.%i.%i_%s" %(ver[0],ver[1],ver[2],ver[4])).replace(' ','')
        else:
            systemInfo="win32_v%i.%i.%i" %(ver[0],ver[1],ver[2])
    else:
        systemInfo = platform.system()+platform.release()
    URL = "http://www.psychopy.org/usage.php?date=%s&sys=%s&version=%s&misc=%s" \
        %(dateNow, systemInfo, v, miscInfo)
    try:
        req = urllib2.Request(URL)
        page = urllib2.urlopen(req)#proxies
    except:
        log.warning("Couldn't connect to psychopy.org\n"+\
            "Check internet settings (and proxy setting in PsychoPy Preferences.")
Example #13
0
def sendUsageStats(proxy=None):
    """Sends anonymous, very basic usage stats to psychopy server:
      the version of PsychoPy
      the system used (platform and version)
      the date

    If http_proxy is set in the system environment variables these will be used automatically,
    but additional proxies can be provided here as the argument proxies.
    """
    v=psychopy.__version__
    dateNow = time.strftime("%Y-%m-%d_%H:%M")
    miscInfo = ''

    #urllib.install_opener(opener)
    #check for proxies
    if proxy in [None,""]:
        pass#use default opener (no proxies)
    else:
        #build the url opener with proxy and cookie handling
        opener = urllib2.build_opener(
            urllib2.ProxyHandler({'http':proxy}))
        urllib2.install_opener(opener)

    #get platform-specific info
    if sys.platform=='darwin':
        OSXver, junk, architecture = platform.mac_ver()
        systemInfo = "OSX_%s_%s" %(OSXver, architecture)
    elif sys.platform=='linux':
        systemInfo = '%s_%s_%s' % (
            'Linux',
            ':'.join([x for x in platform.dist() if x != '']),
            platform.release())
    elif sys.platform=='win32':
        ver=sys.getwindowsversion()
        if len(ver[4])>0:
            systemInfo=("win32_v%i.%i.%i_%s" %(ver[0],ver[1],ver[2],ver[4])).replace(' ','')
        else:
            systemInfo="win32_v%i.%i.%i" %(ver[0],ver[1],ver[2])
    else:
        systemInfo = platform.system()+platform.release()
    URL = "http://www.psychopy.org/usage.php?date=%s&sys=%s&version=%s&misc=%s" \
        %(dateNow, systemInfo, v, miscInfo)
    try:
        req = urllib2.Request(URL)
        page = urllib2.urlopen(req)#proxies
    except:
        log.warning("Couldn't connect to psychopy.org\n"+\
            "Check internet settings (and proxy setting in PsychoPy Preferences.")
Example #14
0
def getLumSeriesPR650(lumLevels=8,
                      winSize=(800, 600),
                      monitor=None,
                      gamma=1.0,
                      allGuns=True,
                      useBits=False,
                      autoMode='auto',
                      stimSize=0.3,
                      photometer='COM1'):
    """DEPRECATED (since v1.60.01): Use :class:`pscyhopy.monitors.getLumSeries()` instead"""

    log.warning(
        "DEPRECATED (since v1.60.01): Use monitors.getLumSeries() instead")
    val = getLumSeries(lumLevels, winSize, monitor, gamma, allGuns, useBits,
                       autoMode, stimSize, photometer)
    return val
Example #15
0
    def show(self):
        """Presents the dialog and waits for the user to press either OK or CANCEL.

        This function returns nothing.

        When they do, dlg.OK will be set to True or False (according to which
        button they pressed. If OK==True then dlg.data will be populated with a
        list of values coming from each of the input fields created.
        """
        #add buttons for OK and Cancel
        buttons = wx.BoxSizer(wx.HORIZONTAL)
        OK = wx.Button(self, wx.ID_OK, " OK ")
        OK.SetDefault()

        buttons.Add(OK)
        CANCEL = wx.Button(self, wx.ID_CANCEL, " Cancel ")
        buttons.Add(CANCEL)
        self.sizer.Add(buttons,
                       1,
                       flag=wx.ALIGN_RIGHT | wx.ALIGN_BOTTOM,
                       border=5)

        self.SetSizerAndFit(self.sizer)
        if self.ShowModal() == wx.ID_OK:
            self.data = []
            #get data from input fields
            for n in range(len(self.inputFields)):
                thisName = self.inputFieldNames[n]
                thisVal = self.inputFields[n].GetValue()
                thisType = self.inputFieldTypes[n]
                #try to handle different types of input from strings
                log.debug("%s: %s" %
                          (self.inputFieldNames[n], unicode(thisVal)))
                if thisType in [tuple, list, float, int]:
                    #probably a tuple or list
                    exec("self.data.append(" + thisVal + ")")  #evaluate it
                elif thisType == numpy.ndarray:
                    exec("self.data.append(numpy.array(" + thisVal + "))")
                elif thisType in [str, unicode, bool]:
                    self.data.append(thisVal)
                else:
                    log.warning('unknown type:' + self.inputFieldNames[n])
                    self.data.append(thisVal)
            self.OK = True
        else:
            self.OK = False
        self.Destroy()
Example #16
0
    def _loadAll(self):
        """Fetches the calibs for this monitor from disk, storing them
        as self.calibs"""

        thisFileName = os.path.join(\
            monitorFolder,
            self.name+".calib")     #the name of the actual file

        if not os.path.exists(thisFileName):
            log.warning("Creating new monitor...")
            self.calibNames = []
        else:
            thisFile = open(thisFileName,'r')
            self.calibs = cPickle.load(thisFile)
            self.calibNames = self.calibs.keys()
            self.calibNames.sort()
            thisFile.close()
Example #17
0
def getLumSeriesPR650(lumLevels=8,
    winSize=(800,600),
    monitor=None,
    gamma=1.0,
    allGuns = True,
    useBits=False,
    autoMode='auto',
    stimSize = 0.3,
    photometer='COM1'):
    """DEPRECATED (since v1.60.01): Use :class:`pscyhopy.monitors.getLumSeries()` instead"""

    log.warning("DEPRECATED (since v1.60.01): Use monitors.getLumSeries() instead")
    val= getLumSeries(lumLevels,
        winSize,monitor,
        gamma,allGuns, useBits,
        autoMode,stimSize,photometer)
    return val
Example #18
0
def gammaInvFun(yy, minLum, maxLum, gamma, eq=1):
    """Returns inverse gamma function for desired luminance values.
    x = gammaInvFun(y, minLum, maxLum, gamma)

    a and b are calculated directly from minLum, maxLum, gamma
    **Parameters:**

        - **xx** are the input values (range 0-255 or 0.0-1.0)
        - **minLum** = the minimum luminance of your monitor
        - **maxLum** = the maximum luminance of your monitor (for this gun)
        - **gamma** = the value of gamma (for this gun)
        - **eq** determines the gamma equation used;
            eq==1[default]: yy = a + (b*xx)**gamma
            eq==2: yy = (a + b*xx)**gamma

    """

    #x should be 0:1
    #y should be 0:1, then converted to minLum:maxLum

    #eq1: y = a + (b*xx)**gamma
    #eq2: y = (a+b*xx)**gamma
    if max(yy)==255:
        yy=numpy.asarray(yy)/255.0
    elif min(yy)<0 or max(yy)>1:
        log.warning('User supplied values outside the expected range (0:1)')

    #get into range minLum:maxLum
    yy = numpy.asarray(yy)*(maxLum - minLum) + minLum

    if eq==1:
        a = minLum
        b = (maxLum-a)**(1/gamma)
        xx = ((yy-a)**(1/gamma))/b
        minLUT = ((minLum-a)**(1/gamma))/b
        maxLUT = ((maxLum-a)**(1/gamma))/b
    elif eq==2:
        a = minLum**(1/gamma)
        b = maxLum**(1/gamma)-a
        xx = (yy**(1/gamma)-a)/b
        maxLUT = (maxLum**(1/gamma)-a)/b
        minLUT = (minLum**(1/gamma)-a)/b

    #then return to range (0:1)
    xx = xx/(maxLUT-minLUT) - minLUT
    return xx
Example #19
0
    def _loadAll(self):
        """Fetches the calibs for this monitor from disk, storing them
        as self.calibs"""

        thisFileName = os.path.join(\
            monitorFolder,
            self.name+".calib")     #the name of the actual file

        if not os.path.exists(thisFileName):
            log.warning("Creating new monitor...")
            self.calibNames = []
        else:
            thisFile = open(thisFileName,'r')
            self.calibs = cPickle.load(thisFile)
            self.calibNames = self.calibs.keys()
            self.calibNames.sort()
            thisFile.close()
Example #20
0
    def onCalibGammaBtn(self, event):

        if NO_MEASUREMENTS:
            #recalculate from previous measure
            lumsPre = self.currentMon.getLumsPre()
            lumLevels = self.currentMon.getLevelsPre()
        else:
            #present a dialogue to get details for calibration
            calibDlg = GammaDlg(self, self.currentMon)
            if calibDlg.ShowModal() != wx.ID_OK:
                calibDlg.Destroy()
                return 1
            nPoints = int(calibDlg.ctrlNPoints.GetStringSelection())
            stimSize = float(calibDlg.ctrlStimSize.GetValue())
            useBits = calibDlg.ctrlUseBits.GetValue()
            calibDlg.Destroy()
            autoMode = calibDlg.methodChoiceBx.GetStringSelection()
            #run the calibration itself
            lumLevels = monitors.DACrange(nPoints)
            lumsPre = monitors.getLumSeries(
                photometer=self.photom,
                lumLevels=lumLevels,
                useBits=useBits,
                autoMode=autoMode,
                winSize=self.currentMon.getSizePix(),
                stimSize=stimSize,
                monitor=self.currentMon)

            #allow user to type in values
            if autoMode == 'semi':
                inputDlg = GammaLumValsDlg(lumLevels, parent=self)
                lumsPre = inputDlg.show()  #will be [] if user cancels
                inputDlg.Destroy()

        #fit the gamma curves
        if len(lumsPre) > 1:
            self.onCopyCalib(1)  #create a new dated calibration
            self.currentMon.setLumsPre(lumsPre)  #save for future
            self.currentMon.setLevelsPre(lumLevels)  #save for future
            self.btnPlotGamma.Enable(True)
            #do the fits
            self.doGammaFits(lumLevels, lumsPre)

        else:
            log.warning('No lum values captured/entered')
Example #21
0
File: gui.py Project: nnb/psychopy
    def show(self):
        """Presents the dialog and waits for the user to press either OK or CANCEL.

        This function returns nothing.

        When they do, dlg.OK will be set to True or False (according to which
        button they pressed. If OK==True then dlg.data will be populated with a
        list of values coming from each of the input fields created.
        """
        #add buttons for OK and Cancel
        buttons = wx.BoxSizer(wx.HORIZONTAL)
        OK = wx.Button(self, wx.ID_OK, " OK ")
        OK.SetDefault()

        buttons.Add(OK)
        CANCEL = wx.Button(self, wx.ID_CANCEL, " Cancel ")
        buttons.Add(CANCEL)
        self.sizer.Add(buttons,1,flag=wx.ALIGN_RIGHT|wx.ALIGN_BOTTOM,border=5)

        self.SetSizerAndFit(self.sizer)
        if self.ShowModal() == wx.ID_OK:
            self.data=[]
            #get data from input fields
            for n in range(len(self.inputFields)):
                thisName = self.inputFieldNames[n]
                thisVal = self.inputFields[n].GetValue()
                thisType= self.inputFieldTypes[n]
                #try to handle different types of input from strings
                log.debug("%s: %s" %(self.inputFieldNames[n], unicode(thisVal)))
                if thisType in [tuple,list,float,int]:
                    #probably a tuple or list
                    exec("self.data.append("+thisVal+")")#evaluate it
                elif thisType==numpy.ndarray:
                    exec("self.data.append(numpy.array("+thisVal+"))")
                elif thisType in [str,unicode,bool]:
                    self.data.append(thisVal)
                else:
                    log.warning('unknown type:'+self.inputFieldNames[n])
                    self.data.append(thisVal)
            self.OK=True
        else:
            self.OK=False
        self.Destroy()
Example #22
0
    def onCalibGammaBtn(self, event):

        if NO_MEASUREMENTS:
            #recalculate from previous measure
            lumsPre = self.currentMon.getLumsPre()
            lumLevels = self.currentMon.getLevelsPre()
        else:
            #present a dialogue to get details for calibration
            calibDlg = GammaDlg(self, self.currentMon)
            if calibDlg.ShowModal()!=wx.ID_OK:
                calibDlg.Destroy()
                return 1
            nPoints = int(calibDlg.ctrlNPoints.GetStringSelection())
            stimSize = float(calibDlg.ctrlStimSize.GetValue())
            useBits = calibDlg.ctrlUseBits.GetValue()
            calibDlg.Destroy()
            autoMode = calibDlg.methodChoiceBx.GetStringSelection()        
            #run the calibration itself
            lumLevels=monitors.DACrange(nPoints)
            lumsPre = monitors.getLumSeries(photometer=self.photom,
                                                 lumLevels=lumLevels,
                                                 useBits=useBits,
                                                 autoMode=autoMode,
                                                 winSize=self.currentMon.getSizePix(),
                                                 stimSize=stimSize, monitor=self.currentMon)
            
            #allow user to type in values
            if autoMode=='semi':
                inputDlg = GammaLumValsDlg(lumLevels, parent=self)
                lumsPre = inputDlg.show()#will be [] if user cancels
                inputDlg.Destroy()
                
        #fit the gamma curves
        if len(lumsPre)>1:
            self.onCopyCalib(1)#create a new dated calibration
            self.currentMon.setLumsPre(lumsPre)#save for future
            self.currentMon.setLevelsPre(lumLevels)#save for future
            self.btnPlotGamma.Enable(True)
            self.choiceLinearMethod.Enable()
            #do the fits
            self.doGammaFits(lumLevels,lumsPre)
        else:
            log.warning('No lum values captured/entered')
Example #23
0
    def measure(self, timeOut=30.0):
        """Make a measurement with the device. For a PR650 the device is instructed 
        to make a measurement and then subsequent commands are issued to retrieve 
        info about that measurement
        """
        t1 = time.clock()
        reply = self.sendMessage('m0\n', timeOut) #measure and hold data
        #using the hold data method the PR650 we can get interogate it
        #several times for a single measurement

        if reply==self.codes['OK']:
            raw = self.sendMessage('d2')
            xyz = raw.split(',')#parse into words
            self.lastQual = str(xyz[0])
            if self.codes[self.lastQual]=='OK':
                self.lastLum = float(xyz[3])
            else: self.lastLum = 0.0
        else:
            log.warning("Didn't collect any data (extend timeout?)")
Example #24
0
    def measure(self, timeOut=30.0):
        """Make a measurement with the device. For a PR650 the device is instructed 
        to make a measurement and then subsequent commands are issued to retrieve 
        info about that measurement
        """
        t1 = time.clock()
        reply = self.sendMessage('m0\n', timeOut)  #measure and hold data
        #using the hold data method the PR650 we can get interogate it
        #several times for a single measurement

        if reply == self.codes['OK']:
            raw = self.sendMessage('d2')
            xyz = raw.split(',')  #parse into words
            self.lastQual = str(xyz[0])
            if self.codes[self.lastQual] == 'OK':
                self.lastLum = float(xyz[3])
            else:
                self.lastLum = 0.0
        else:
            log.warning("Didn't collect any data (extend timeout?)")
Example #25
0
    def __init__(
        self,
        win,
        contrast=1.0,
        gamma=[1.0, 1.0, 1.0],
        nEntries=256,
        bitsType='bits++',
    ):
        self.win = win
        self.contrast = contrast
        self.nEntries = nEntries
        self.bitsType = bitsType
        self.method = 'fast'

        if len(gamma) > 2:  # [Lum,R,G,B] or [R,G,B]
            self.gamma = gamma[-3:]
        else:
            self.gamma = [gamma, gamma, gamma]

        if init():
            setVideoMode(NOGAMMACORRECT | VIDEOENCODEDCOMMS)
            self.initialised = True
            log.debug('found and initialised bits++')
        else:
            self.initialised = False
            log.warning("couldn't initialise bits++")

        #do the processing
        self._HEADandLUT = numpy.zeros((524, 1, 3), numpy.uint8)
        self._HEADandLUT[:12, :, 0] = numpy.asarray(
            [36, 63, 8, 211, 3, 112, 56, 34, 0, 0, 0, 0]).reshape([12, 1])  #R
        self._HEADandLUT[:12, :, 1] = numpy.asarray(
            [106, 136, 19, 25, 115, 68, 41, 159, 0, 0, 0, 0]).reshape([12,
                                                                       1])  #G
        self._HEADandLUT[:12, :, 2] = numpy.asarray(
            [133, 163, 138, 46, 164, 9, 49, 208, 0, 0, 0, 0]).reshape([12,
                                                                       1])  #B
        self.LUT = numpy.zeros((256, 3), 'd')  #just a place holder
        self.setLUT()  #this will set self.LUT and update self._LUTandHEAD
Example #26
0
def rgb2dklCart(picture, conversionMatrix=None):
    """convert an RGB image into Cartesian DKL space"""
    #Turn the picture into an array so we can do maths
    picture = numpy.array(picture)
    #Find the original dimensions of the picture
    origShape = picture.shape

    #this is the inversion of the dkl2rgb conversion matrix
    if conversionMatrix == None:
        conversionMatrix = numpy.asarray([\
            #LUMIN->%L-M->L+M-S

            [ 0.25145542,  0.64933633,  0.09920825],
            [ 0.78737943, -0.55586618, -0.23151325],
            [ 0.26562825,  0.63933074, -0.90495899]])
        log.warning(
            'This monitor has not been color-calibrated. Using default DKL conversion matrix.'
        )
    else:
        conversionMatrix = numpy.linalg.inv(conversionMatrix)

    #Reshape the picture so that it can multiplied by the conversion matrix
    red = picture[:, :, 0]
    green = picture[:, :, 1]
    blue = picture[:, :, 2]

    dkl = numpy.asarray(
        [red.reshape([-1]),
         green.reshape([-1]),
         blue.reshape([-1])])

    #Multiply the picture by the conversion matrix
    dkl = numpy.dot(conversionMatrix, dkl)

    #Reshape the picture so that it's back to it's original shape
    dklPicture = numpy.reshape(numpy.transpose(dkl), origShape)
    return dklPicture
Example #27
0
def rush(value=True):
    """Raise the priority of the current thread/process using 
        - sched_setscheduler
    
    NB for rush() to work on (debian-based?) linux requires that the script is run using a copy of python that
    is allowed to change priority, eg: sudo setcap cap_sys_nice=eip <sys.executable>, and maybe restart PsychoPy.
    If <sys.executable> is the system python, its important to restore it back to normal to avoid possible 
    side-effects. Alternatively, use a different python executable, and change its cap_sys_nice.
    
    For RedHat-based systems, 'sudo chrt ...' at run-time might be needed instead, not sure.
    see http://rt.et.redhat.com/wiki/images/8/8e/Rtprio.pdf
    """
    if importCtypesFailed: return False

    if value:  #set to RR with max priority
        schedParams = _SchedParams()
        schedParams.sched_priority = c.sched_get_priority_max(SCHED_RR)
        err = c.sched_setscheduler(0, SCHED_RR, ctypes.byref(schedParams))
        if err == -1:  #returns 0 if OK
            log.warning(
                """Failed to raise thread priority with sched_setscheduler.
To enable rush(), if you are using a debian-based linux, try this in a terminal window:
  'sudo setcap cap_sys_nice=eip %s'  [NB: You may need to install 'setcap' first.]
If you are using the system's python (eg /usr/bin/python2.x), its highly recommended
to change cap_sys_nice back to normal afterwards:
  'sudo setcap cap_sys_nice= %s'""" % (sys.executable, sys.executable))
    else:  #set to RR with normal priority
        schedParams = _SchedParams()
        schedParams.sched_priority = c.sched_get_priority_min(SCHED_NORMAL)
        err = c.sched_setscheduler(0, SCHED_NORMAL, ctypes.byref(schedParams))
        if err == -1:  #returns 0 if OK
            log.warning(
                """Failed to set thread priority back to normal level with sched_setscheduler.
Try:  'sudo setcap cap_sys_nice= %s'""" % (sys.executable))

    return True
Example #28
0
    def installZipFile(self, zfile, v=None):
        """If v is provided this will be used as new version number, otherwise try and retrieve
        a version number from zip file name 
        """
        info=""#return this at the end
        
        if type(zfile) in [str, unicode] and os.path.isfile(zfile):#zfile is filename not an actual file
            if v==None: #try and deduce it
                zFilename = os.path.split(zfile)[-1]
                searchName = re.search('[0-9]*\.[0-9]*\.[0-9]*.', zFilename)
                if searchName!=None:
                    v=searchName.group(0)[:-1]
                else:log.warning("Couldn't deduce version from zip file: %s" %zFilename)
            f=open(zfile)
            zfile=zipfile.ZipFile(f)
        else:#assume here that zfile is a ZipFile
            pass#todo: error checking - is it a zipfile?
            
        currPath=self.app.prefs.paths['psychopy']
        #any commands that are successfully executed may need to be undone if a later one fails
        undoString = ""
        #depending on install method, needs diff handling
        #if path ends with 'psychopy' then move it to 'psychopy-version' and create a new 'psychopy' folder for new version
        versionLabelsInPath = re.findall('PsychoPy-.*/',currPath)#does the path contain any version number?
        if len(versionLabelsInPath)==0:#e.g. the mac standalone app, no need to refer to new versino number
            unzipTarget=currPath
            try: #to move existing PsychoPy
                os.rename(currPath, "%s-%s" %(currPath, psychopy.__version__))
                undoString += 'os.rename("%s-%s" %(currPath, psychopy.__version__),currPath)\n'
            except:
                if sys.platform=='win32' and int(sys.getwindowsversion()[1])>5:
                    msg = "Right-click the app and 'Run as admin' to upgrade)"
                else:
                    msg = "Could not move existing PsychoPy installation (permissions error?)"
                return msg
        else:#setuptools-style installation
            #generate new target path
            unzipTarget=currPath
            for thisVersionLabel in versionLabelsInPath:
                pathVersion=thisVersionLabel[:-1]#remove final slash from the re.findall
                unzipTarget=unzipTarget.replace(pathVersion, "PsychoPy-%s" %v)
                # find the .pth file that specifies the python dir
                #create the new installation directory BEFORE changing pth file
                nUpdates, newInfo = self.updatePthFile(pathVersion, "PsychoPy-%s" %v)
                if nUpdates==-1:#there was an error (likely permissions)
                    undoString += 'self.updatePthFile(unzipTarget, currPath)\n'
                    exec(undoString)#undo previous changes
                    return newInfo
                
        try:
            os.makedirs(unzipTarget)#create the new installation directory AFTER renaming existing dir
            undoString += 'os.remove(%s)\n' %unzipTarget
        except: #revert path rename and inform user
            exec(undoString)#undo previous changes
            if sys.platform=='win32' and int(sys.getwindowsversion()[1])>5:
                msg = "Right-click the app and 'Run as admin'):\n%s" %unzipTarget
            else:
                msg = "Failed to create directory for new version (permissions error?):\n%s" %unzipTarget
            return msg

        #do the actual extraction
        for name in zfile.namelist():#for each file within the zip
            #check that this file is part of the psychopy (not metadata or docs)
            if name.count('/psychopy/')<1: continue
            try:
                targetFile = os.path.join(unzipTarget, name.split('/psychopy/')[1])
                targetContainer=os.path.split(targetFile)[0]
                if not os.path.isdir(targetContainer):
                    os.makedirs(targetContainer)#make the containing folder
                if targetFile.endswith('/'):
                    os.makedirs(targetFile)#it's a folder                
                else:
                    outfile = open(targetFile, 'wb')
                    outfile.write(zfile.read(name))
                    outfile.close()
            except:
                exec(undoString)#undo previous changes
                print 'failed to unzip file:', name
                print sys.exc_info()[0]
        info += 'Success. \nChanges to PsychoPy will be completed when the application is next run'
        self.cancelBtn.SetDefault()
        self.installBtn.Disable()
        return info
Example #29
0
    def installZipFile(self, zfile, v=None):
        """If v is provided this will be used as new version number, otherwise try and retrieve
        a version number from zip file name 
        """
        info = ""  #return this at the end

        if type(zfile) in [
                str, unicode
        ] and os.path.isfile(zfile):  #zfile is filename not an actual file
            if v == None:  #try and deduce it
                zFilename = os.path.split(zfile)[-1]
                searchName = re.search('[0-9]*\.[0-9]*\.[0-9]*.', zFilename)
                if searchName != None:
                    v = searchName.group(0)[:-1]
                else:
                    log.warning("Couldn't deduce version from zip file: %s" %
                                zFilename)
            f = open(zfile)
            zfile = zipfile.ZipFile(f)
        else:  #assume here that zfile is a ZipFile
            pass  #todo: error checking - is it a zipfile?

        currPath = self.app.prefs.paths['psychopy']
        #any commands that are successfully executed may need to be undone if a later one fails
        undoString = ""
        #depending on install method, needs diff handling
        #if path ends with 'psychopy' then move it to 'psychopy-version' and create a new 'psychopy' folder for new version
        versionLabelsInPath = re.findall(
            'PsychoPy-.*/',
            currPath)  #does the path contain any version number?
        if len(
                versionLabelsInPath
        ) == 0:  #e.g. the mac standalone app, no need to refer to new versino number
            unzipTarget = currPath
            try:  #to move existing PsychoPy
                os.rename(currPath, "%s-%s" % (currPath, psychopy.__version__))
                undoString += 'os.rename("%s-%s" %(currPath, psychopy.__version__),currPath)\n'
            except:
                if sys.platform == 'win32' and int(
                        sys.getwindowsversion()[1]) > 5:
                    msg = "Right-click the app and 'Run as admin' to upgrade)"
                else:
                    msg = "Could not move existing PsychoPy installation (permissions error?)"
                return msg
        else:  #setuptools-style installation
            #generate new target path
            unzipTarget = currPath
            for thisVersionLabel in versionLabelsInPath:
                pathVersion = thisVersionLabel[:
                                               -1]  #remove final slash from the re.findall
                unzipTarget = unzipTarget.replace(pathVersion,
                                                  "PsychoPy-%s" % v)
                # find the .pth file that specifies the python dir
                #create the new installation directory BEFORE changing pth file
                nUpdates, newInfo = self.updatePthFile(pathVersion,
                                                       "PsychoPy-%s" % v)
                if nUpdates == -1:  #there was an error (likely permissions)
                    undoString += 'self.updatePthFile(unzipTarget, currPath)\n'
                    exec(undoString)  #undo previous changes
                    return newInfo

        try:
            os.makedirs(
                unzipTarget
            )  #create the new installation directory AFTER renaming existing dir
            undoString += 'os.remove(%s)\n' % unzipTarget
        except:  #revert path rename and inform user
            exec(undoString)  #undo previous changes
            if sys.platform == 'win32' and int(sys.getwindowsversion()[1]) > 5:
                msg = "Right-click the app and 'Run as admin'):\n%s" % unzipTarget
            else:
                msg = "Failed to create directory for new version (permissions error?):\n%s" % unzipTarget
            return msg

        #do the actual extraction
        for name in zfile.namelist():  #for each file within the zip
            #check that this file is part of the psychopy (not metadata or docs)
            if name.count('/psychopy/') < 1: continue
            try:
                targetFile = os.path.join(unzipTarget,
                                          name.split('/psychopy/')[1])
                targetContainer = os.path.split(targetFile)[0]
                if not os.path.isdir(targetContainer):
                    os.makedirs(targetContainer)  #make the containing folder
                if targetFile.endswith('/'):
                    os.makedirs(targetFile)  #it's a folder
                else:
                    outfile = open(targetFile, 'wb')
                    outfile.write(zfile.read(name))
                    outfile.close()
            except:
                exec(undoString)  #undo previous changes
                print 'failed to unzip file:', name
                print sys.exc_info()[0]
        info += 'Success. \nChanges to PsychoPy will be completed when the application is next run'
        self.cancelBtn.SetDefault()
        self.installBtn.Disable()
        return info
Example #30
0
from psychopy import log

#create a log that gets replaced every run and stores all the details
detailedLog =  log.LogFile('complete.log', 
    'w', #'a' will append to previous file, 'w' will overwrite
    level=log.INFO)

#set the level of the console log
log.console.setLevel(log.WARNING)

#set the level of the log at site-packages/psychopy/psychopy.log
log.psychopyLog.setLevel(log.ERROR)

log.warning('a shot across the bows')
log.error('just a test error message')
log.info('this will only get sent to the detailed log file')
Example #31
0
 def setLUT(self,newLUT=None, gammaCorrect=True, LUTrange=1.0):		
     """Sets the LUT to a specific range of values.
     
     Note that, if you leave gammaCorrect=True then any LUT values you supply
     will automatically be gamma corrected.
     
     If BitsBox setMethod is 'fast' then the LUT will take effect on the next 
     ``Window.update()`` If the setMethod is 'slow' then the update will take 
     place over the next 1-4secs down the USB port. 
     
     **Examples:**
         ``bitsBox.setLUT()``
         	builds a LUT using bitsBox.contrast and bitsBox.gamma
         
         ``bitsBox.setLUT(newLUT=some256x1array)``
             (NB array should be float 0.0:1.0)
             Builds a luminance LUT using newLUT for each gun 
             (actually array can be 256x1 or 1x256)
         
         ``bitsBox.setLUT(newLUT=some256x3array)``
            (NB array should be float 0.0:1.0)
            Allows you to use a different LUT on each gun
         
     (NB by using BitsBox.setContr() and BitsBox.setGamma() users may not
     need this function!?)
     """
                
     #choose endpoints
     LUTrange=numpy.asarray(LUTrange)
     if LUTrange.size==1:
         startII = int(round((0.5-LUTrange/2.0)*255.0))
         endII = int(round((0.5+LUTrange/2.0)*255.0))+1 #+1 because python ranges exclude last value
     elif LUTrange.size==2:
         multiplier=1.0
         if LUTrange[1]<=1: multiplier=255.0
         startII= int(round(LUTrange[0]*multiplier))
         endII = int(round(LUTrange[1]*multiplier))+1 #+1 because python ranges exclude last value
     stepLength = 2.0/(endII-startII-1)
     
     if newLUT is None:
         #create a LUT from scratch (based on contrast and gamma)
         #rampStep = 2.0/(self.nEntries-1)
         ramp = numpy.arange(-1.0,1.0+stepLength, stepLength)
         ramp = (ramp*self.contrast+1.0)/2.0
         #self.LUT will be stored as 0.0:1.0 (gamma-corrected)
         self.LUT[startII:endII,0] = copy(ramp)
         self.LUT[startII:endII,1] = copy(ramp)
         self.LUT[startII:endII,2] = copy(ramp)
     elif type(newLUT) in [float, int] or (newLUT.shape==()):            
         self.LUT[startII:endII,0]= newLUT
         self.LUT[startII:endII,1]= newLUT
         self.LUT[startII:endII,2]= newLUT
     elif len(newLUT.shape) == 1: #one dimensional LUT
         #replicate LUT to other channels
         #check range is 0:1
         if newLUT>1.0:
             log.warning('newLUT should be float in range 0.0:1.0')
         self.LUT[startII:endII,0]= copy(newLUT.flat)
         self.LUT[startII:endII,1]= copy(newLUT.flat)
         self.LUT[startII:endII,2]= copy(newLUT.flat)
         
     elif len(newLUT.shape) == 2: #one dimensional LUT
         #use LUT as is
         #check range is 0:1
         if max(max(newLUT))>1.0:
             raise AttributeError, 'newLUT should be float in range 0.0:1.0'				
         self.LUT[startII:endII,:]= newLUT
         
     else:
         log.warning('newLUT can be None, nx1 or nx3')
         
     #do gamma correction if necessary
     if gammaCorrect==True:
         gamma=self.gamma
         if hasattr(self.win.monitor, 'lineariseLums'):   
             self.LUT[startII:endII, : ] = self.win.monitor.lineariseLums(self.LUT[startII:endII, : ], overrideGamma=gamma)
             
     #update the bits++ box with new LUT
     if self.method=='fast':
         #get bits into correct order, shape and add to header
         ramp16 = (self.LUT*(2**16-1)).astype(numpy.uint16) #go from ubyte to uint16
         ramp16 = numpy.reshape(ramp16,(256,1,3))
         #set most significant bits 
         self._HEADandLUT[12::2,:,:] = (ramp16[:,:,:]>>8).astype(numpy.uint8)
         #set least significant bits
         self._HEADandLUT[13::2,:,:] = (ramp16[:,:,:]&255).astype(numpy.uint8)
         self._HEADandLUTstr = self._HEADandLUT.tostring()
Example #32
0
import glob
from psychopy import core, log, hardware

log.console.setLevel(log.DEBUG)

pr655 = hardware.findPhotometer(device="PR655")
if pr655 == None:
    log.warning("no device found")
else:
    print "type:", pr655.type
    print "SN:", pr655.getDeviceSN()
    pr655.measure()
    print "lum", pr655.lastLum
    print "uv", pr655.lastUV
    print "xy", pr655.lastXY
    print "tristim", pr655.lastTristim
    nm, spec = pr655.getLastSpectrum()
    print "nm", nm
    print "spec", spec
    print "temperature", pr655.lastColorTemp

print "DONE"
Example #33
0
from psychopy import log

#create a log that gets replaced every run and stores all the details
detailedLog = log.LogFile(
    'complete.log',
    'w',  #'a' will append to previous file, 'w' will overwrite
    level=log.INFO)

#set the level of the console log
log.console.setLevel(log.WARNING)

#set the level of the log at site-packages/psychopy/psychopy.log
log.psychopyLog.setLevel(log.ERROR)

log.warning('a shot across the bows')
log.error('just a test error message')
log.info('this will only get sent to the detailed log file')
Example #34
0
"""Deprecated - use the monitors package rather than psychopy.calib
"""
# Part of the PsychoPy library
# Copyright (C) 2010 Jonathan Peirce
# Distributed under the terms of the GNU General Public License (GPL).

from psychopy import log
log.warning("psychopy.calib is deprecated - use monitors package instead")
from monitors import *
Example #35
0
    def setLUT(self, newLUT=None, gammaCorrect=True, LUTrange=1.0):
        """Sets the LUT to a specific range of values.
        
        Note that, if you leave gammaCorrect=True then any LUT values you supply
        will automatically be gamma corrected.
        
        If BitsBox setMethod is 'fast' then the LUT will take effect on the next 
        ``Window.update()`` If the setMethod is 'slow' then the update will take 
        place over the next 1-4secs down the USB port. 
        
        **Examples:**
            ``bitsBox.setLUT()``
                builds a LUT using bitsBox.contrast and bitsBox.gamma
            
            ``bitsBox.setLUT(newLUT=some256x1array)``
                (NB array should be float 0.0:1.0)
                Builds a luminance LUT using newLUT for each gun 
                (actually array can be 256x1 or 1x256)
            
            ``bitsBox.setLUT(newLUT=some256x3array)``
               (NB array should be float 0.0:1.0)
               Allows you to use a different LUT on each gun
            
        (NB by using BitsBox.setContr() and BitsBox.setGamma() users may not
        need this function!?)
        """

        #choose endpoints
        LUTrange = numpy.asarray(LUTrange)
        if LUTrange.size == 1:
            startII = int(round((0.5 - LUTrange / 2.0) * 255.0))
            endII = int(round(
                (0.5 + LUTrange / 2.0) *
                255.0)) + 1  #+1 because python ranges exclude last value
        elif LUTrange.size == 2:
            multiplier = 1.0
            if LUTrange[1] <= 1: multiplier = 255.0
            startII = int(round(LUTrange[0] * multiplier))
            endII = int(round(
                LUTrange[1] *
                multiplier)) + 1  #+1 because python ranges exclude last value
        stepLength = 2.0 / (endII - startII - 1)

        if newLUT is None:
            #create a LUT from scratch (based on contrast and gamma)
            #rampStep = 2.0/(self.nEntries-1)
            ramp = numpy.arange(-1.0, 1.0 + stepLength, stepLength)
            ramp = (ramp * self.contrast + 1.0) / 2.0
            #self.LUT will be stored as 0.0:1.0 (gamma-corrected)
            self.LUT[startII:endII, 0] = copy(ramp)
            self.LUT[startII:endII, 1] = copy(ramp)
            self.LUT[startII:endII, 2] = copy(ramp)
        elif type(newLUT) in [float, int] or (newLUT.shape == ()):
            self.LUT[startII:endII, 0] = newLUT
            self.LUT[startII:endII, 1] = newLUT
            self.LUT[startII:endII, 2] = newLUT
        elif len(newLUT.shape) == 1:  #one dimensional LUT
            #replicate LUT to other channels
            #check range is 0:1
            if newLUT > 1.0:
                log.warning('newLUT should be float in range 0.0:1.0')
            self.LUT[startII:endII, 0] = copy(newLUT.flat)
            self.LUT[startII:endII, 1] = copy(newLUT.flat)
            self.LUT[startII:endII, 2] = copy(newLUT.flat)

        elif len(newLUT.shape) == 2:  #one dimensional LUT
            #use LUT as is
            #check range is 0:1
            if max(max(newLUT)) > 1.0:
                raise AttributeError, 'newLUT should be float in range 0.0:1.0'
            self.LUT[startII:endII, :] = newLUT

        else:
            log.warning('newLUT can be None, nx1 or nx3')

        #do gamma correction if necessary
        if gammaCorrect == True:
            gamma = self.gamma
            if hasattr(self.win.monitor, 'lineariseLums'):
                self.LUT[startII:endII, :] = self.win.monitor.lineariseLums(
                    self.LUT[startII:endII, :], overrideGamma=gamma)

        #update the bits++ box with new LUT
        if self.method == 'fast':
            #get bits into correct order, shape and add to header
            ramp16 = (self.LUT * (2**16 - 1)).astype(
                numpy.uint16)  #go from ubyte to uint16
            ramp16 = numpy.reshape(ramp16, (256, 1, 3))
            #set most significant bits
            self._HEADandLUT[12::2, :, :] = (ramp16[:, :, :] >> 8).astype(
                numpy.uint8)
            #set least significant bits
            self._HEADandLUT[13::2, :, :] = (ramp16[:, :, :] & 255).astype(
                numpy.uint8)
            self._HEADandLUTstr = self._HEADandLUT.tostring()
Example #36
0
    10:DEBUG
So setting to DEBUG level will include all possible messages, setting to ERROR will include only the absolutely essential messages.

"""
globalClock = core.Clock()#if this isn't provided the log times will reflect secs since python started
log.setDefaultClock(globalClock)#use this for 

log.console.setLevel(log.DEBUG)#set the console to receive nearly all messges
logDat = log.LogFile('logLastRun.log', 
    filemode='w',#if you set this to 'a' it will append instead of overwriting
    level=log.WARNING)#errors, data and warnings will be sent to this logfile

#the following will go to any files with the appropriate minimum level set
log.info('Something fairly unimportant')
log.data('Something about our data. Data is likely very important!')
log.warning('Handy while building your experiment - highlights possible flaws in code/design')
log.error("You might have done something that PsychoPy can't handle! But hopefully this gives you some idea what.")

#some things should be logged timestamped on the next video frame
#For instance the time of a stimulus appearing is related to the flip:
win = visual.Window([400,400])
for n in range(5):
    win.logOnFlip('frame %i occured' %n, level=log.EXP)
    if n in [2,4]:
        win.logOnFlip('an even frame occured', level=log.EXP)
    win.flip()
    
#LogFiles can also simply receive direct input from the write() method
#messages using write() will be sent immediately, and are often not
#in correct chronological order with logged messages
logDat.write("Testing\n\n")
Example #37
0
"""Deprecated - use the monitors package rather than psychopy.calib
"""
# Part of the PsychoPy library
# Copyright (C) 2011 Jonathan Peirce
# Distributed under the terms of the GNU General Public License (GPL).

from psychopy import log
log.warning("psychopy.calib is deprecated - use monitors package instead")
from monitors import *
Example #38
0
"""
globalClock = core.Clock(
)  #if this isn't provided the log times will reflect secs since python started
log.setDefaultClock(globalClock)  #use this for

log.console.setLevel(log.DEBUG)  #set the console to receive nearly all messges
logDat = log.LogFile(
    'logLastRun.log',
    filemode='w',  #if you set this to 'a' it will append instead of overwriting
    level=log.WARNING)  #errors, data and warnings will be sent to this logfile

#the following will go to any files with the appropriate minimum level set
log.info('Something fairly unimportant')
log.data('Something about our data. Data is likely very important!')
log.warning(
    'Handy while building your experiment - highlights possible flaws in code/design'
)
log.error(
    "You might have done something that PsychoPy can't handle! But hopefully this gives you some idea what."
)

#some things should be logged timestamped on the next video frame
#For instance the time of a stimulus appearing is related to the flip:
win = visual.Window([400, 400])
for n in range(5):
    win.logOnFlip('frame %i occured' % n, level=log.EXP)
    if n in [2, 4]:
        win.logOnFlip('an even frame occured', level=log.EXP)
    win.flip()

#LogFiles can also simply receive direct input from the write() method