I am new to Psychopy having never used the programme before.
I would like to use Psychopy to run a colour experiment.
Does anyone have a colour experiment (modulations in DKL space) using
Psychopy that I can use. It would better if I could see an already
constructed colour experiment (modulations in DKL space) and make
modifications to understand better how psychopy works.
Any help would be very much appreciated.
Many thanks in advance,
Joanne
Alex
-Alex
#!/usr/bin/env python
#by Alex Holcombe, 2011
#when run, must hit space to advance frames
#you must have a monitor with its full matrix defined in Tools-
>MonitorCenter
from psychopy import visual, event, core, log, monitors, misc
import copy
import numpy as np
import numpy
import math as m
from scipy import linalg
gotTexttable = True
try:
from texttable import *
except:
gotTexttable = False
#demo color spaces
#note that for this demo to present colors properly in calibrated
#DKL space (where isoluminant stimuli have elevation=0) you need
#to calibrate your monitor with a suitable spectrophotometer. If you
#have a PR60 then you can do this automatically using MonitorCenter.py
#in the monitors package
exportImages=False
monitorname='2mitsu'
autopilot = False
#mon='temp' #has gammas to 1,1,1
#because my monitor tops out, I will have to use my own luminance
conversion function to go from desired rgb luminance to rgb255 (with
gamma=1)
#then convert any dklCart I want to rgb
#so, pull latest calibration from monitor center, then manually set
gammas to 1
#monitorname = 'test' # used to be 'mitsubishi' but that was with
gamma=1. In case I've calibrated it and set a gamma, shouldn't use
it. #in psychopy Monitors Center
#mon = monitors.Monitor(monitorname)#fetch the most recent calib for
this monitor
#lums = mon.getLumsPre() #all the lums that were recorded
#fit function. First, exclude numbers where saturate. Then fit
function. Then
#saturationLevel = 249
#lumsExcludeSaturatn = lums[:,0:saturationLevel]
#levels=monitors.DACrange(256)
#for gun in [0,1,2,3]:
# gamCalc = monitors.GammaCalculator(levels, lums[gun,:],
eq=linMethod)
# currentCal[gun,0]=lums[gun,0]#min
# currentCal[gun,1]=lums[gun,-1]#max
# currentCal[gun,2]=gamCalc.gammaVal#gamma
#find some luminances for red and for yellow that work
waitBlank = False
mon = monitors.Monitor(monitorname)#relying on monitorwidth cm (39
for Mitsubishi to do deg calculations)
dkl2rgbMatrix = mon.getDKL_RGB()
gammaGrid = mon.getGammaGrid()
minLums = gammaGrid[1:4,0]
maxLums = gammaGrid[1:4,1] #skip 0 which is for all 3 guns combined
print 'dkl2rgbMatrix for this screen =',dkl2rgbMatrix
print 'minLums=',np.around(minLums,2)
print 'maxLums=',np.around(maxLums,2)
print 'gamma grid for this screen, not including minLum and maxLum=
\n',np.around(gammaGrid[:,2::],decimals=2)
DACceil=248#looks like ceiling happens around DAC=248
#convert from luminance to DACvalue? I don't think that's provided as
a inbuilt psychopy function
def RGB255ToLum(gun,rgb,gammaGrid):
#a+(b+kx)^g #this is a complete equation, so don't have to do any
scaling except bring 0->255 into 0->1
g = gammaGrid[gun+1,2] #e.g. 2.19
a = gammaGrid[gun+1,3] #e.g. 1.47
b = gammaGrid[gun+1,4] #e.g. 0.39
k = gammaGrid[gun+1,5] #e.g. 3.80
x = rgb/255.0 #need to discretize
lum = a + (b+k*x)**g
return (lum)
def lumToRGB255notlinearized(gun,lum,gammaGrid):
#lum specified in candelas per meter squared
#requires that lum be greater than minlum, otherwise nan
#lum=a+(b+kx)^g #(b+kx)^g = lum-a #b+kx = (lum-a)^(1/g) #kx =
(lum-a)^(1/g) - b #x = (lum-a)^(1/g) - b / k
g = gammaGrid[gun+1,2]; a = gammaGrid[gun+1,3]; b = gammaGrid[gun
+1,4]; k = gammaGrid[gun+1,5]
if lum < a:
print 'WARNING lumToRGB255: desired lum should be greater than
minimum lum for this gun, ',a
x = (lum-a)**(1./g)/k - b/k
return (x*255)
lumCeil = np.array([0.,0.,0.])
for guni in range(3): #calculate luminance where guns saturate, based
on hand-entered DACceil observed during calibration
lumCeil[guni] = RGB255ToLum(guni,DACceil,gammaGrid)
print 'lumCeil = ',lumCeil
#for a phosphor, calculate its RGB value to get this particular
luminance
#def lumToOneGunRGB(lum,gun): #lum from -1 (minimum of screen) to +1
(maximum of screen)
#print 'lumToRGB255 blue gun: l, rgb',
#for l in np.arange(-1,1.0,.05):
# proportn = l+1./2. #from -1->1 to 0->1
# minLum = minLums[2]; maxLum = maxLums[2] #gammaGrid[2+1,3];
maxLum = gammaGrid[2+1,4];
# lumWanted = (maxLum-minLum)*l + minLum
# print l,' lumWanted=',lumWanted,' rgb',
lumToRGB255notlinearized(2,lumWanted,gammaGrid)
#KLcartLumToRGB255(guni,lum,gammaGrid)
#go from DKLcart lum to phosphor rgb
def DKLcartLumToPhosphorRGB(gun,lum,gammaGrid):
#for a partcular DKLcartLum (-1->1), give corresponding rgb value
for a single phosphor to get that luminance
purePhosphor =[-1,-1,-1]; purePhosphor[gun] = 1
dklCartPhosphor = linalg.solve( dkl2rgbMatrix, purePhosphor )
maxLumThisGunDKL = dklCartPhosphor[0]
minLumThisGunDKL = linalg.solve( dkl2rgbMatrix, [-1,-1,-1] ) [0]
print 'minLumThisGunDKL,
maxLumThisGunDKL=',minLumThisGunDKL,maxLumThisGunDKL
proportnLum = (lum-minLumThisGunDKL) / (maxLumThisGunDKL-
minLumThisGunDKL)
minLum = minLums[gun]; maxLum = maxLums[gun]
#but are these luminances that gamma compensates linearly related
to L+M used in DKLcart ?
#that's determined by the first column of the dkl2rgb matrix,
which in my case is 1,1,1 so assume it's that
lumCandelas = (maxLum-minLum)*proportnLum + minLum
#rgb (linearized) for this gun is simply proportion of luminance
range
rgb = [-1,-1,-1]
rgb[gun] = proportnLum * 2. -1
dklCart = linalg.solve( dkl2rgbMatrix, rgb )
print 'these nums should be equal:', lum, round(dklCart[0],3),
'and yield rgb=',np.around(np.array(rgb),3)
return (rgb)
print 'DKLcartLum of -.5 for red, rgb=',DKLcartLumToPhosphorRGB(0,-.
5,gammaGrid)
print 'DKLcartLum of -.5 for green, rgb=',DKLcartLumToPhosphorRGB(1,-.
5,gammaGrid)
print 'DKLcartLum of -.5 for blue, rgb=',DKLcartLumToPhosphorRGB(2,-.
5,gammaGrid)
print 'DKLcartLum of -1 for red,
rgb=',DKLcartLumToPhosphorRGB(0,-1,gammaGrid)
print 'DKLcartLum of -1 for green,
rgb=',DKLcartLumToPhosphorRGB(1,-1,gammaGrid)
def cart2sph( ar ):
#ar is numpy array
r = m.sqrt(ar[0]**2 + ar[1]**2 + ar[2]**2) # r
elev = m.atan2(ar[0],m.sqrt(ar[1]**2+ar[2]**2)) # theta
# elev = m.atan2(ar[2],m.sqrt(XsqPlusYsq)) # theta
az = m.atan2(ar[2],ar[1]) # phi
# az = m.atan2(ar[1],ar[0]) # phi
elev = elev/m.pi*180 #convert from radians to degrees
az = az/m.pi*180 #convert from radians to degrees
sph = np.array( [elev,az,r] )
return sph
def dklSphericalToCart(dkl_Nx3):
#dklCartesian(Nx3) = dklSphericalToCart(dkl_Nx3(el,az,radius))
dkl_3xN = np.transpose(dkl_Nx3)#its easier to use in the other
orientation!
if np.size(dkl_3xN)==3:
RG, BY, LUM = misc.sph2cart(dkl_3xN[0],dkl_3xN[1],dkl_3xN[2])
else:
RG, BY, LUM =
misc.sph2cart(dkl_3xN[0,:],dkl_3xN[1,:],dkl_3xN[2,:])
dkl_cartesian = np.asarray([LUM, RG, BY])
return dkl_cartesian
#
#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)
# print 'Entered dkl2rgb with dkl_Nx3 = ',dkl_Nx3
# dkl_3xN = numpy.transpose(dkl_Nx3)#its easier to use in the other
orientation!
# if numpy.size(dkl_3xN)==3:
# RG, BY, LUM = misc.sph2cart(dkl_3xN[0],dkl_3xN[1],dkl_3xN[2])
# else:
# RG, BY, LUM =
misc.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)
# print 'dkl2rgb converted dkl to rgb with
dkl_cartesian=',dkl_cartesian , ' whereas my cartesian conversion
yields ', dklSphericalToCart(dkl_Nx3),
# print ' and rgb result is = ',rgb
#
# return numpy.transpose(rgb)#return in the shape we received it
#dkl spherical. Elevation (90 is pure luminance), Azimuth (0 is L-M,
90 is S-(L+M), Contrast/Radius -1 to 1
dklRedSpherical = [0.,0.,1.]; dklSconeYellowSpherical = [0.,90.,1.];
dklSconeBlueSpherical = [0.,-90.,1.]
#dkl cartesian LUM, RG, BY
dklRedCartCalculated = dklSphericalToCart(dklRedSpherical);
dklSconeBlueCartCalculated = dklSphericalToCart(dklSconeBlueSpherical)
dklRedCartesian = [0.,1.,0.]
print 'dklRedCartCalculated = ',dklRedCartCalculated, ' whereas I
thought it would be ',dklRedCartesian
print 'dklSconeBlueCartCalculated = ', dklSconeBlueCartCalculated
rgbRed = misc.dkl2rgb( dklRedSpherical, dkl2rgbMatrix ); rgbSconeBlue
= misc.dkl2rgb( dklSconeBlueSpherical , dkl2rgbMatrix)
print 'rgbRed from dkl is ', np.around(rgbRed,2) #0,0,0 for some
reason
print 'rgbSconeBlue from dkl is ', np.around(rgbSconeBlue,2)
#Because I'm interested in getting maximally differential colors,
maybe I should use pure guns, but use psychopy code to tell me what
the color coordinates are
#and the luminance? No because with yellow manipulation want to
maintain constant chromaticity.
#So maybe I should determine chromaticity of canonical yellow. Then
adjust luminance of that.
#try to convert rgb back to dkl
#linalg.solve(A, B) # Computes the "exact" solution, x, of the
well-determined, i.e., full rank, linear matrix equation Ax = B
#for conversion of RGB to DKL, A is the DKL->RGB conversion matrix and
B is the RGB coordinates
dklRedBackwardsCheck = linalg.solve(dkl2rgbMatrix, rgbRed)
print 'dklRedBackwardsCheck = ', np.around( dklRedBackwardsCheck, 2)
#it works
dklSconeBlueBackwardsCheck = linalg.solve(dkl2rgbMatrix, rgbSconeBlue)
print 'dklSconeBlueBackwardsCheck = ',
np.around( dklSconeBlueBackwardsCheck, 2), \
'versus dklSconeBlueCartCalculated = ',
np.around( dklSconeBlueCartCalculated, 2 )
dklRedGunOnly = linalg.solve(dkl2rgbMatrix, [1,-1,-1])
print 'dklRedGunOnly = ', np.around(dklRedGunOnly, 2)
unitsSupplement = ['', '90=lum,0=L-M,90=S,contrast/radius', '', '',
'', '','']
columns= ['name', 'DKL sph', 'DKL cart', 'RGB', 'DKL cart', 'DKL sph',
'RGB']
units=['', 'elev,az,r', 'LUM,GR,BY', 'R,G,B', 'LUM,GR,BY',
'elev,az,r' , 'R,G,B' ]
def calcEveryThingFromDKL(dkl_3xN, dkl2rgbMatrix):
dklSph = dkl_3xN
dklCart = dklSphericalToCart( dklSph )
rgb = misc.dkl2rgb ( dklSph, dkl2rgbMatrix )
#should rgb be 1x3 ( row) or 3x1 (column) ?
dklCartFromRGB = linalg.solve( dkl2rgbMatrix, rgb )
dklSphFromRGB = cart2sph( dklCartFromRGB )
return 'NA', dklSph, dklCart, rgb, dklCartFromRGB, dklSphFromRGB,
'NA'
def arrayOfTripletsToListOfStrs( arrayTriplets, decimals=2 ):
listStrs = list()
for t in arrayTriplets:
tripletNoBrackets = ''
for i in t: #for each number in the tripletNoBrackets
if type(i) != type(str()): #if it's not a string, turn it
into array and round it
i = np.around( np.array(i), decimals)
tripletNoBrackets += str(i) + ' '
listStrs.append( tripletNoBrackets )
return listStrs
everythingDklRed = list( calcEveryThingFromDKL( dklRedSpherical,
dkl2rgbMatrix ) ); everythingDklRed[0]='red Lcone'
everythingDklSconeYellow =
list( calcEveryThingFromDKL( dklSconeYellowSpherical,
dkl2rgbMatrix ) ); everythingDklSconeYellow[0]='yellow Scone'
everythingDklSconeBlue =
list( calcEveryThingFromDKL( dklSconeBlueSpherical, dkl2rgbMatrix ) );
everythingDklSconeBlue[0]='blue Scone'
everythingDklRedToPrint =
arrayOfTripletsToListOfStrs( everythingDklRed )
everythingDklSconeBlueToPrint =
arrayOfTripletsToListOfStrs( everythingDklSconeBlue )
everythingDklSconeYellowToPrint =
arrayOfTripletsToListOfStrs( everythingDklSconeYellow )
def calcEveryThingFromRGB(rgb_3xN, dkl2rgbMatrix):
rgb = rgb_3xN
dklCart = linalg.solve( dkl2rgbMatrix, rgb )
dklSph = cart2sph( dklCart )
rgbFromDklSph = misc.dkl2rgb ( dklSph, dkl2rgbMatrix )
return 'NA', 'NA', 'NA', rgb, dklCart, dklSph, rgbFromDklSph
purePhosphors = [ [1,-1,-1], [1,1,-1], [-1,-1,1] ]#add pure color guns
to see their color coordinates
purePhosphorsNames=['redGun','greenGun','blueGun']
if gotTexttable:
table = Texttable()
table.add_row(unitsSupplement)
table.add_row(columns)
table.add_row(units)
table.add_row( everythingDklRedToPrint )
table.add_row( everythingDklSconeBlueToPrint )
table.add_row( everythingDklSconeYellowToPrint )
for rgb,name in zip(purePhosphors,purePhosphorsNames):
#print rgb,name
cols = list( calcEveryThingFromRGB(rgb, dkl2rgbMatrix) )
cols[0] = name
colsToPrint = arrayOfTripletsToListOfStrs( cols )
table.add_row( colsToPrint )
#take pure red, but with luminance of -.5 and see how that does
redPatchBrightestDkl = copy.deepcopy( dklRedCartesian )
patchTopLum = -.6
dklCartRed = linalg.solve( dkl2rgbMatrix, [.9,-.2,-.2] )
dklCartYel = [-.4,0,0.2] # linalg.solve( dkl2rgbMatrix, [.3,.5,-.2] )
#[.07, .38, .87] # [-.55,.76,1.73]
dklCartBlue = linalg.solve( dkl2rgbMatrix,[-.8,-.8,1] )
#dklCartRed = redPatchBrightestDkl
#dklCartYel= dklSphericalToCart(dklSconeYellowSpherical)
#dklCartBlue= dklSphericalToCart(dklSconeBlueSpherical)
dklCartRed[0] = patchTopLum
dklCartYel[0] = patchTopLum
dklCartBlue[0] = patchTopLum
everything_dklCartRed=
list( calcEveryThingFromDKL( cart2sph(dklCartRed), dkl2rgbMatrix ) );
everything_dklCartRed[0]='redPatch'
if gotTexttable:
table.add_row( arrayOfTripletsToListOfStrs(everything_dklCartRed) )
everything_dklCartYel=
list( calcEveryThingFromDKL( cart2sph(dklCartYel), dkl2rgbMatrix ) );
everything_dklCartYel[0]='yelPatch'
if gotTexttable:
table.add_row( arrayOfTripletsToListOfStrs(everything_dklCartYel) )
everything_dklCartBlue=
list( calcEveryThingFromDKL( cart2sph(dklCartBlue), dkl2rgbMatrix ) );
everything_dklCartBlue[0]='bluPatch'
if gotTexttable:
table.add_row( arrayOfTripletsToListOfStrs(everything_dklCartBlue) )
if gotTexttable: print table.draw()
scrn=1 #1
fullscr=1 #1
allowGUI=True
winSize=(800,600) #(1024,768)
myWin =
visual.Window(monitor=mon,size=winSize,allowGUI=allowGUI,fullscr=fullscr,screen=scrn,colorSpace='name',color='black')
#draw luminance gradient using DKL of red next to luminance gradient
of a good yellow
allStim = list();
stepsInGradient = 12
topLumDkl = dklCartRed[0]
portionOfLumRangeToSpan = .6
lumStepDkl = (topLumDkl - -1)*portionOfLumRangeToSpan /
stepsInGradient #because spans -1 to 1
def makeLine(x,y,width,fillColorSpace,fillColor,orientation):
halfW =width/2.
rectangularVertices = [ [+halfW,-.9], [-halfW,-.9], [-halfW,+.9],
[+halfW,+.9] ]
line = visual.ShapeStim(myWin,
lineColorSpace='rgb',lineColor=[-1,-1,-1],
fillColorSpace=fillColorSpace, fillColor=fillColor,
units='norm',
lineWidth=1, #in pixels. must be greater than 0
vertices=rectangularVertices,#choose something from
the above or make your own
closeShape=True,#do you want the final vertex to
complete a loop with 1st?
interpolate=True,
ori=orientation,
pos= [x,y], #the anchor (rotaion and vertices are
position with respect to this)
autoLog=False)#this stim changes too much for
autologging to be useful
return (line)
def
makeSquare(width,lineColorSpace,lineColor,fillColorSpace,fillColor):
halfW =width/2.
sqrVertices = [ [halfW,-halfW], [-halfW,-halfW], [-halfW,halfW],
[halfW,halfW] ]
square = visual.ShapeStim(myWin,
lineColorSpace=lineColorSpace, lineColor=lineColor,
fillColorSpace=fillColorSpace, fillColor=fillColor,
units='norm',
lineWidth=1.0, #in pixels
vertices=sqrVertices,#choose something from the above
or make your own
closeShape=True,#do you want the final vertex to
complete a loop with 1st?
interpolate=True,
pos= [0.5,0.5], #the anchor (rotaion and vertices are
position with respect to this)
autoLog=False)#this stim changes too much for
autologging to be useful
return (square)
# import matplotlib
# matplotlib.use('WXAgg')
# from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
as FigureCanvas
# from matplotlib.figure import Figure
#plot DKLcart space
from psychopy import log
log.console.setLevel(log.CRITICAL) #don't print warnings because takes
time
stop=False
repetitions =1
if exportImages:
repetitions = 7 #to make 2 per second, have to show each frame
many times
for lum in np.arange(-.904,.9,.001): #np.arange(-.9,.9,.1):
for reps in range(repetitions):
colorStim=list()
lumText =
visual.TextStim(myWin,colorSpace='rgb',color=(1,1,1),ori=0,height=.
06,wrapWidth=999,alignHoriz='center', units='norm',autoLog=False)
lumText.setPos([0,.85]);
lumText.setText('L+M= '+str(round(lum,2))+ ' -1 is
minimum of screen, +1 is maximum')
colorStim.append(lumText)
stepsInGradient = 40
GRmin = -1.4 #-1.7;
GRmax = 2.0 #1.8
BYmin = -2.0 #-1.7;
BYmax = 1.4 #1.8
screenPortionToUse = .8
spacing = screenPortionToUse*2.0/stepsInGradient
xposMin = -screenPortionToUse*2.0/2 +.05
yposMin = -screenPortionToUse*2.0/2 +.05
GRstep = (GRmax-GRmin)*1.0/stepsInGradient
BYstep = (BYmax-BYmin)*1.0/stepsInGradient
labelSpacing = .1; labelFreq = round(labelSpacing/spacing)
grAxisText = visual.TextStim(myWin,colorSpace='rgb',color=(1,1,1),
height=.05, alignHoriz='center', units='norm',autoLog=False)
grAxisText.setPos([0,yposMin-spacing*2.6]); grAxisText.setText('GR
(L-M)')
colorStim.append(grAxisText)
byAxisText =
visual.TextStim(myWin,colorSpace='rgb',color=(1,1,1),ori=-90, height=.
05, alignHoriz='center', units='norm',autoLog=False)
byAxisText.setPos([xposMin-spacing*2.9,0]); byAxisText.setText('BY
(L+M)-S')
colorStim.append(byAxisText)
for GRi in range(stepsInGradient):
GR = GRmin + GRstep*GRi
xpos = xposMin + GRi*spacing
grStr=''
if GRi % labelFreq ==0: #draw GR text
grText =
visual.TextStim(myWin,colorSpace='rgb',color=(1,1,1), height=.05,
alignHoriz='center', units='norm',autoLog=False)
grText.setPos([xpos,yposMin-1.3*spacing]);
grStr = str(round(GR,2))
grText.setText(grStr);
colorStim.append( grText )
for BYi in range(stepsInGradient):
ypos = yposMin + BYi*spacing
BY = BYmin + BYstep*BYi
if GRi==0 and (BYi %labelFreq==0): #create y coordinate
text
byText =
visual.TextStim(myWin,colorSpace='rgb',color=(1,1,1), height=.05,
alignHoriz='center', units='norm',autoLog=False)
byText.setPos([xposMin-1.3*spacing,ypos]);
byStr = str(round(BY,2))
byText.setText(byStr);
colorStim.append( byText )
#create color patch
dklCart = [lum,GR,BY]
width = spacing*.8
height = spacing*.8
dklSph = cart2sph(dklCart)
rgb = misc.dkl2rgb ( dklSph, dkl2rgbMatrix ) #check my Dkl
to RGB conversion is working, visually
if np.any(np.array(rgb)**2.0>1.0): #if any desired RGB
values are outside gamut, drawsomething else instead
#print rgb
square = makeSquare(width*.9,'rgb',[-.9,-1,-.
9],'rgb',None)
square.setPos([xpos,ypos])
#colorStim.append( square ) #to save memory, of which I
run out, don't draw these
else:
square = makeSquare(width*.95,'rgb',
[1.,1.,1.],'dkl',dklSph)
#enclose it with a white circle so it shows up even if
wrong gamma
square.setPos([xpos,ypos])
colorStim.append( square )
#determine rgb values of phosphors for this luminance and the DKL
coordinates
phosphors=list();
for guni in range(0,3):
rgb= DKLcartLumToPhosphorRGB(guni,lum,gammaGrid)
rgb=np.array(rgb)
print 'rgb=',rgb
dklCart = linalg.solve( dkl2rgbMatrix, rgb )
print 'these nums should be equal:', lum, round(dklCart[0],3)
x = xposMin + (dklCart[1] - GRmin) / GRstep * spacing
y = yposMin + (dklCart[2] - BYmin) / BYstep * spacing
if not np.any(rgb**2>1): #not out of range
phosText =
visual.TextStim(myWin,colorSpace='rgb',color=rgb, height=.08,
alignHoriz='center',alignVert='center',units='norm',autoLog=False)
gunNames = ['R','G','B']
phosText.setText( gunNames[guni] )
phosText.setPos([x,y])
colorStim.append(phosText)
phosTextColor=[-1,-1,-1]; phosTextColor[guni]=1
phosTextNum =
visual.TextStim(myWin,colorSpace='rgb',color=phosTextColor,height=.05,
alignHoriz='center',alignVert='center',units='norm',autoLog=False)
phosTextNum.setText( str(round(dklCart[1],2))
+','+str(round(dklCart[2],2)) )
offsetAngles = [45,135,225]; offsetVec =
misc.pol2cart(offsetAngles[guni],.08)
phosTextNum.setPos([x+offsetVec[0],y+offsetVec[1]])
colorStim.append(phosTextNum)
#add lines for cartesian axes of graph
x = xposMin + (0 - GRmin) / GRstep * spacing
y = yposMin + (0 - BYmin) / BYstep * spacing
hline = makeLine(x,y,.005,'rgb',[0.1,0.1,0.1],0)
colorStim.append(hline)
vline = makeLine(x,y,.005,'rgb',[0.1,0.1,0.1],90)
colorStim.append(vline)
for thisStim in colorStim: #draw graph for this luminance
thisStim.draw()
myWin.flip()
if exportImages:
myWin.getMovieFrame(buffer='front') #for later saving
if not autopilot:
for key in event.getKeys(): #wait for key
if key in ['escape','q']: #check if pressed abort-type
key
stop=True
if not autopilot and not exportImages:
event.waitKeys() #wait until key hit
del colorStim #free memory
if exportImages:
myWin.saveMovieFrames('exported/frame.png')
#myWin.saveMovieFrames('exported/stimuli.mov', fps=1)
myWin.close(); core.quit()
#want to draw adjacent patches for minimally distinct border method
Jon
On 28/11/2011 23:49, Alex Holcombe wrote:
> installation at least a, b, and k of the linearisation table are NaN.
> I think this is an oversight that should probably be fixed in a later
> version of Psychopy.
--
Jonathan Peirce
Nottingham Visual Neuroscience
This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham.
This message has been checked for viruses but the contents of an attachment
may still contain software viruses which could damage your computer system:
you are advised to perform your own checks. Email communications with the
University of Nottingham may be monitored as permitted by UK legislation.
Hi everyone,This must be mind numbingly simple, but I am having trouble getting my font to change. Here is my code. I certainly don't see a problem.from psychopy import event,visualfrom string import letters,digitswin = visual.Window(units='pix')text = visual.TextStim(win=win,text=' '.join(letters+digits),height=30,wrapWidth=400)
for font in ['Times New Roman','Arial','Courier']:
-- Dr. Jonathan Peirce Nottingham Visual Neuroscience http://www.peirce.org.uk/