Skip to content

Commit

Permalink
Awh and Fukuda VSTM task from Quant not Qual. This is ColorIndiv version
Browse files Browse the repository at this point in the history
  • Loading branch information
machow committed Apr 4, 2012
0 parents commit 2defb09
Show file tree
Hide file tree
Showing 25 changed files with 694 additions and 0 deletions.
Binary file added .DS_Store
Binary file not shown.
Binary file added ._.DS_Store
Binary file not shown.
Binary file added ._drawStims.py
Binary file not shown.
Binary file added ._drawStims.pyc
Binary file not shown.
Binary file added ._shapes.py
Binary file not shown.
Binary file added ._shapes.pyc
Binary file not shown.
16 changes: 16 additions & 0 deletions data/9.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
1 N B N B A 4 3 shapes B 0 False 9 (7.8670768943017677, -1.4914653639559141) (-8.409656593042266, -2.8144611061696496) (-8.0804010793360046, 4.0054554569572005) (4.2178678338839166, 7.8313971036362773) 1.0 slash 0.685998
2 N A B N M 4 2 shapes B 0 False 9 (4.2464205552807535, -6.8173306040906407) (1.5955404097999022, 8.6885517024948236) (-2.2070847255166841, 5.5209765137600915) (-4.2150098913659271, -0.62291222783768951) 1.0 slash 0.78517
3 M A N A B 4 2 shapes N 0 False 9 (-5.071852423396539, 7.9814993072395239) (7.6345086585107893, -2.4969092115231906) (1.8611159067398688, 8.4638527358962214) (-0.76090695240490724, -2.9177332097101942) 1.0 slash 0.479162
4 N B M A B 4 3 shapes A 0 False 9 (-1.3499525105812333, 0.64023603710738186) (-7.8104139653168767, -8.7170101339916304) (2.9136769300927874, -8.5794714053696666) (5.6089985278277474, 7.9833201847395969) 1.0 slash 0.37794
5 N A N B M 4 3 shapes B 0 False 9 (4.1117474021891773, -5.1813373972324204) (-0.40574647847038392, -0.17653214041867216) (3.6882307516961639, 3.9046743934364425) (-6.8696783940444348, 1.3546177124744752) 1.0 slash 0.600779
6 M B M N M 4 1 shapes B 0 False 9 (-1.8098661115823074, -0.87604565268332824) (7.6110350152998478, 2.6231119287299727) (-2.2976360674151337, 8.1746684706879087) (0.14015109779801449, -4.6166038322257501) 1.0 slash 0.390241
7 N B N M M 4 2 shapes N 0 False 9 (5.0834726840321967, -6.2819468997322261) (2.6804791012986549, 0.71786455018573747) (-5.6090527983580163, 1.5306867168551825) (-8.5854484365947545, -7.4856587041949965) 1.0 slash 0.580526
8 N A A M B 4 2 shapes A 0 False 9 (-2.5706002365003746, -2.5144775729358591) (-5.9844721965766228, 2.6649898764207105) (2.3710606252203537, -6.0432504907931692) (3.3095210751947484, 5.8621724741012535) 1.0 slash 0.49845
1 P D P P D 4 0 shapes P 1 False 9 (2.7211527343958757, 6.0699541248324937) (-1.2071923641898854, 4.486494256668804) (-3.1123073654485225, -2.6715702197448765) (8.5146227657693458, -2.773982792446005) 1.0 slash 0.640781
2 O D P O P 4 1 shapes D 1 False 9 (2.2165201700805444, -7.044158016544265) (-2.884561924606972, 2.7919657105631277) (-7.8493312498339112, -3.6496039853604731) (4.0114369966016739, 1.668371791171003) 1.0 slash 0.468234
3 P D O C P 4 2 shapes O 1 False 9 (2.4413844416820307, -6.9679271563871392) (-4.6545425602607899, 8.1946524595109196) (-8.6568316872850417, -2.8734042534396851) (1.7218566743334307, 3.143953156504196) 1.0 slash 0.487054
4 P C O O C 4 3 shapes O 1 False 9 (-7.1116279584424849, -1.9589733046914235) (5.7611418801772594, -7.3684334705721435) (-3.4911161453275747, 1.4915606848485634) (2.7443156351598983, 4.6734075769012531) 1.0 slash 0.689221
5 O D C C O 4 2 shapes C 1 False 9 (-3.8215811848834198, 6.7069979202377041) (1.5967588941811517, -4.0036254716171467) (6.4182871428046298, 7.1916588921521338) (-7.6044778522130096, -0.55050711708110356) 1.0 slash 0.506402
6 O C P D P 4 1 shapes C 1 False 9 (7.8375237481272038, 0.97737096325096928) (3.4003076492398705, -2.5458631819159958) (-7.4199299170159367, -2.8215194559865839) (-2.5118665035088945, 5.7632554964163685) 1.0 slash 0.491967
7 O D P O C 4 2 shapes P 1 False 9 (-5.9509832195165533, 6.575963470643444) (5.7325942777996364, 5.7741344422939651) (5.3551869372829728, -4.1944374673272433) (-6.3930834118569182, -0.79177285719671797) 1.0 slash 0.50145
8 P C D P O 4 0 shapes P 1 False 9 (0.10719198622865278, 7.5301575442929973) (6.8497877966360434, -1.9371589241647111) (-2.2962488773308545, -3.7291598653730791) (-7.9979399180799025, 4.409290473328987) 1.0 slash 0.390918
313 changes: 313 additions & 0 deletions data/all.txt

Large diffs are not rendered by default.

232 changes: 232 additions & 0 deletions drawStims.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
from psychopy import visual, event, core, data
from shapes import taskTrials, pracTrials
import random

win = visual.Window(fullscr = True, units = 'deg', monitor = 'testMonitor', color = 'lightgrey')
win.setRecordFrameIntervals()
mouse = event.Mouse(win = win)
mouse.setVisible(False)
refresh_HZ = 100
refresh_rate = 1./refresh_HZ
frameMargin = 2*10**(-3)
pre_flip_time = refresh_rate - frameMargin
#upper bound for view times (will subtract one frame from time ans
fixation_on_time = .75 - pre_flip_time
fixation_off_time = .25 - pre_flip_time
view_stims_time = .5 - pre_flip_time
stims_memory_time = 1. - pre_flip_time



font_dir = 'circle_square.otf'
font_name = 'Circle_Square'

#
textStims = [visual.PatchStim(win, tex = 'stims/A.png', size = (2.5,1.75), mask = None, interpolate = False) for ii in range(10)]
rectStims = [visual.Rect(win, height = 1.5, width = 1.5, lineWidth = 1, interpolate = False) for ii in range(10)]

#range will be 17.5 x 17.5 degrees

SQUARES = ['M', 'N', 'O', 'P', 'Q', 'R']
OVALS = ['A','B','C','D','E','F']


def drawStims(win, stims, posList, textStims, rectStims, loadOnly = False):
if type(stims) == str: stims = [stims]
for ii, stim in enumerate(stims):
if len(stim) == 1:
textStims[ii].draw()
else:
rectStims[ii].draw()

def loadStims(win, stims, posList, textStims, rectStims, loadOnly = False):
if type(stims) == str: stims = [stims]
for ii, stim in enumerate(stims):
if len(stim) == 1:
textStims[ii].setPos(posList[ii])
if stim in OVALS: textStims[ii].setSize((2.5, 2.5))
else: textStims[ii].setSize((2.5,2.5))
textStims[ii].setTex('stims/'+stim+'.png')
print stims
print(stim in OVALS)
else:
rectStims[ii].setFillColor(stim)
rectStims[ii].setLineColor(stim)
rectStims[ii].setPos(posList[ii])

def switchPos(itemStim, foilStim):
'''pure convenience function. Switches positions from item to foil'''
foilStim.setpos(itemStim.pos)

def drawProbe(stim):
stim.draw()

def drawFixation(fixationStim):
fixationStim.draw()

def waitScreen(win, myMouse, maxViewingTime = 100000, lastTime = 0, onClick = True):
'''Either waits for a mouse click or until maxViewingTime has elapsed'''
done = False
clock = core.Clock()
myMouse.clickReset()
lastTime = myMouse.getPressed(getTime=True)[1][0]
while not done:
click, time = myMouse.getPressed(getTime=True)
if onClick and click[0] and time[0] != lastTime:
done = True
lastTime = time[0]
if clock.getTime() > maxViewingTime: return lastTime
return lastTime

def waitResponse(maxWait = None, clock = None, reset = True, keyList = ['z', 'slash']):
if not clock:
clock = core.Clock()
if reset: clock.reset()
event.clearEvents()
needResp = True
while needResp:
keys = event.getKeys(keyList, timeStamped = True)
if keys:
needResp = False
return keys[0][0], clock.getTime() #resp, rt

def flipandwait(win, clock=None, viewTime=1):
if not clock: clock = core.Clock()
win.flip()
clock.reset()
while clock.getTime() < viewTime: pass

from psychopy import visual
def instructions(pracTrials):
text_1 = '''In this task, items will be presented in different locations on the screen.
Your job is to remember the items presented on the screen, as well as their location.
Items will be either colored squares or shapes.
Hit spacebar to continue'''
text_2 = '''
Hit spacebar for a slowed-down example of seeing the colored squares
'''
text_3 = '''
Hit spacebar for see a slowed-down example of seeing the shapes
'''

text_4 = '''
After seeing some items, a single test item will appear on screen.
The test item will be in the same position as one of the previous items.
Do your best to identify whether the previous item from that position matches the test item.
Mismatches may be different shapes, or the inside of the shape may be different.
Press the 'Z' key if they match
Press the '/' key if they are different
Hit spacebar to practice the task
'''

text_5 = '''
In the actual task, the items will be presented more quickly
Hit spacebar to practice the actual task
'''

text_6 = '''
Now you will begin the actual task.
If you have any questions, please ask the experimenter now.
Hit spacebar to continue to the actual task'''
textStims = [visual.PatchStim(win, tex = 'stims/A.png', size = (2.5,1.75), mask = None, interpolate = False) for ii in range(5)]
rectStims = [visual.Rect(win, height = 1.5, width = 1.5, lineWidth = 1, interpolate = False) for ii in range(5)]
Text = visual.TextStim(win, text = text_1, color = "black", wrapWidth = 25)
examplePos1 = [(-2.8, -5.8),
(2.3, -3.9),
(8.5, 0.4),
(-1.7, 0.8)]
examplePos2 = [(7.2, -3.9),
(0.8, 0.2),
(-3.5, 2.7),
(-7.3, -2.9)]
Text.setAutoDraw(True)
flipandwait(win, viewTime = 4)
waitResponse(maxWait = None, clock = None, reset = True, keyList = ['space'])
Text.setText(text_2)
flipandwait(win, viewTime = .5)
waitResponse(maxWait = None, clock = None, reset = True, keyList = ['space'])
Text.setAutoDraw(False)
#Examples of item presentation
#loadStims(win, ['black', 'red', 'yellow', 'green'], examplePos1, textStims, rectStims)
#drawStims(win, ['black', 'red', 'yellow', 'green'], examplePos1, textStims, rectStims)
#flipandwait(win, viewTime = 1.5)
Text.setText(text_3)
Text.draw()
flipandwait(win, viewTime = .5)
waitResponse(maxWait = None, clock = None, reset = True, keyList = ['space'])
loadStims(win, ['P', 'A', 'B', 'R'], examplePos2, textStims, rectStims)
drawStims(win, ['P', 'A', 'B', 'R'], examplePos2, textStims, rectStims)
flipandwait(win, viewTime = 1.5)
#Run-through a full example
Text.setText(text_4)
Text.draw()
flipandwait(win, viewTime = 3)
waitResponse(maxWait = None, clock = None, reset = True, keyList = ['space'])
#Practice
#Text.setText(text_5)
#Text.draw()
#flipandwait(win, viewTime = 1)
#waitResponse(maxWait = None, clock = None, reset = True, keyList = ['space'])
runTask(pracTrials)
Text.setText(text_6)
Text.draw()
flipandwait(win, viewTime = 1)
waitResponse(maxWait = None, clock = None, reset = True, keyList = ['space'])

def runTrial(win, rtClock, stims, posList, probeItem, probePos,
fixationStim = None, fixation_on_time = .75, fixation_off_time = .25,
view_stims_time = .5, stims_memory_time = 1, header = True):
if not fixationStim: fixationStim = visual.TextStim(win, text = '+', color = 'black')
loadStims(win, stims, posList, textStims, rectStims)
#FIXATION
drawFixation(fixationStim) #fixation on
flipandwait(win, rtClock, fixation_on_time)
flipandwait(win, rtClock, fixation_off_time) #fixation off
#STIMULI
loadStims(win, stims, posList, textStims, rectStims)
drawStims(win, stims, posList, textStims, rectStims)
flipandwait(win, rtClock, view_stims_time)
#INTER-RESPONSE INTERVAL
flipandwait(win, rtClock, stims_memory_time)
#CHANGE DETECTION TEST
loadStims(win, probeItem, probePos, textStims, rectStims)
drawStims(win, probeItem, probePos, textStims, rectStims)
win.flip()
resp, rt = waitResponse(clock = rtClock)
return resp, rt


def runTask(taskTrials, append = True, header = True):
rtClock = core.Clock()
frameClock = core.Clock()
fixationStim = visual.TextStim(win, text = '+', color = 'black')
for thisTrial in taskTrials:
posList = [thisTrial['stim.pos%s'%ii] for ii in range(thisTrial['ttl.stims'])]
stims = [thisTrial['stim%s'%ii] for ii in range(thisTrial['ttl.stims'])]
resp, rt = runTrial(win, rtClock, stims, posList, thisTrial['stim.probe'], [posList[thisTrial['corr.num']]],
fixationStim, fixation_on_time, fixation_off_time, view_stims_time, stims_memory_time, header)

taskTrials.data.add('resp', resp)
taskTrials.data.add('RT', rt)
core.wait(1)
taskTrials.saveAsWideText('data/all', appendFile = append, matrixOnly = True)
taskTrials.saveAsWideText('data/' + str(thisTrial['Subject']), appendFile = append, matrixOnly = not header)

#instructions(pracTrials)
for trials in taskTrials:
runTask(trials, header = False)


#runTrial(win, core.Clock(), ['A', 'B','C','D'], zip(range(-6, 6, 3), range(-6,6,3)), ['A'], (-6,-6))
1 change: 1 addition & 0 deletions miscpy/centerimages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import PIL
13 changes: 13 additions & 0 deletions miscpy/example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from psychopy import visual, core
import os

os.getcwd()
font_dir = 'circle_square.otf' #may need to change this to point to font
font_name = 'circle_square'
letters = ['A', 'B', 'C', 'D', 'E', 'F']

win = visual.Window()
textStims = [ visual.TextStim(win, text = letters[ii], bold = True, fontFiles = [font_dir], font = 'Circle_Square', height = .1 + ii/10. , color = 'black', pos = (-.5+ ii/(5.), -.5+ ii/(5.))) for ii in range(5) ]
for stim in textStims: stim.draw()
win.flip()
core.wait(5)
119 changes: 119 additions & 0 deletions shapes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
from psychopy import data
import random
import math

participantNum = 9


def genPos(numStims, constraint, boxHor, boxVer, threshold = None):
posList = []
if not threshold: threshold = math.ceil(numStims / 4) #stims distributed evenly through quadrants
for ii in range(numStims):
tooClose = True #Start loop
while tooClose:
tooClose = False #Assume the best
newpos = (random.random()*boxHor - (boxHor/2), random.random()*boxVer - (boxVer/2)) #new random pos
for otherpos in posList: #compare to other positions
if distance(newpos, otherpos) < constraint: tooClose = True #redraw if too close
quad = [quadrant(pos) for pos in posList]
if quad.count(quadrant(newpos)) == threshold: tooClose = True #fails constraint

posList.append(newpos)
return posList

def quadrant(pos):
if pos[0] >= 0 <= pos[1]: return 1 #top-right
if pos[0] < 0 < pos[1]: return 2 #top-left
if pos[0] < 0 > pos[1]: return 3 #bottom-left
if pos[0] >= 0 > pos[1]: return 4 #bottom-right

def addConstraints(newpos, posList, threshold = 1):
quad = [quadrant(pos) for pos in posList]
if quad.count(quadrant(newpos)) == threshold: return True #fails constraint
def distance(posA, posB):
diffs = [(coordA - coordB)**2 for coordA,coordB in zip(posA, posB)]
return sum(diffs)**(1./2)



def sampleShapes(SQUARES, OVALS, k, uniquesquares, uniqueovals, randomdraw = True):
stims = random.sample(SQUARES, uniquesquares)
stims.extend(random.sample(OVALS, uniqueovals))
if randomdraw:
toDraw = max(k-(uniquesquares + uniqueovals), 0)
drawFrom = SQUARES+OVALS
#maxEle_ii = len(drawFrom)-1
#stims.extend([drawFrom[random.randint(0, maxEle_ii)] for round in range(toDraw)])
while len(stims) < k:
newdraw = random.sample(drawFrom, 1)
if stims.count(newdraw) == 2: continue
else: stims.extend(newdraw)
return stims
elif k % (uniquesquares + uniqueovals) == 0:
stims = stims*(k / (uniquesquares + uniqueovals))
random.shuffle(stims)
return stims
else: raise
def sampleColors(stims, k, repeats):
sampled = []
while len(sampled) < k:
newdraw = stims[random.randint(0, len(stims)-1)]
if sampled.count(newdraw) == repeats: continue
else: sampled.append(newdraw)
return sampled


def genTrials(blockNum, shape_trials, shape_lures, col_trials, col_lures, num_stims, min_dist, grid_size, participantNum):
selection = (blockNum%3)*2 if (type(blockNum) == int) else (0)
SQUARES = ['M', 'N', 'O', 'P', 'Q', 'R'][selection:selection+2]
OVALS = ['A','B','C','D','E','F'][selection:selection+2]
COLORS = ['red', 'blue', 'green', 'yellow', 'black', 'white']
trialList = []

for ttlStims in num_stims:
luresLeft = {'shapes':shape_lures, 'colors':col_lures}
stimsDict = {'shapes':SQUARES + OVALS, 'colors': COLORS}
trialType = ['shapes']*shape_trials + ['colors']*col_trials
for trial in trialType:
posList = genPos(ttlStims, min_dist, grid_size[0], grid_size[1])
if trial == 'shapes':
stims = sampleShapes(SQUARES, OVALS, ttlStims, 1, 1)
else: stims = sampleColors(COLORS, ttlStims, repeats = 2)
probeNum = random.randint(0, ttlStims - 1) #probe num
if luresLeft[trial] > 0:
luresLeft[trial] = luresLeft[trial] - 1
luresList = [item for item in stimsDict[trial] if item != stims[probeNum]]
probe = random.sample(luresList, 1)[0]
else: probe = stims[probeNum]
d = dict([('stim%s'%ii, val) for ii, val in enumerate(stims)])
print probe, '\t', probeNum, '\t', stims[probeNum]
d.update( [('Subject', participantNum), ('block',str(blockNum)), ('stim.probe', probe), ('corr.num', probeNum), ('stim.corr', stims[probeNum]), ('match', probe == stims[probeNum]), ('trial.type', trial), ('ttl.stims', ttlStims)] )
d.update([('stim.pos%s'%ii , pos) for ii, pos in enumerate(posList)]) #clunky but python2.6 compatible
trialList.append(d)
return trialList

Blocks = 9
######
#trials per block
shape_trials = 8#16 #per set size
shape_lures = 8#8 #per set size
col_trials = 0#8 #"
col_lures = 0#4
num_stims = [4]

min_dist = 4
grid_size = (17.5, 17.5)
#test trials
trialLists = [genTrials(ii, shape_trials, shape_lures, col_trials, col_lures, num_stims, min_dist, grid_size, participantNum = participantNum) for ii in range(Blocks)]
#practice trials
pracList = genTrials('Practice', 4, 2, 0, 0, [4, 8], min_dist, grid_size, participantNum = participantNum)


taskTrials = [data.TrialHandler(trialLists[ii], 1) for ii in range(len(trialLists))]
for handlerNum in range(len(trialLists)):
taskTrials[handlerNum].data.addDataType('resp')
taskTrials[handlerNum].data.addDataType('RT')
pracTrials = data.TrialHandler(pracList, 1)
pracTrials.data.addDataType('resp')
pracTrials.data.addDataType('RT')

Binary file added stims/A.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added stims/B.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added stims/C.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added stims/D.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added stims/E.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added stims/F.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added stims/M.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added stims/N.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added stims/O.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added stims/P.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added stims/Q.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added stims/R.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added stims/circle_square.otf
Binary file not shown.

0 comments on commit 2defb09

Please sign in to comment.