How to use
This is the main source code for the experiment. If you want to use it, you should copy the actual zip file to your own PsyToolkit account, because often there are other files included for stimuli.
The source code for retrocue
options
#--basic parameters---------------------------------------
set &stimulus_width 147 # needed for the background image to color stimuli, note the images are 148px, but reduce by one to remove outline
set &encoding_timeTraining 3000 # used for training
set &encoding_timeNormal 1000 # in paper it is 1000ms, but for testing can try more
set &errorCutOff 40 ## 40 degrees in moving window
set &movingWindow 4 ## how many trials back for calculating error rate
set &totalTrialsTodo 130 # this is just for the feedback to participants and is constant
#---------------------------------------------------------
mouse on
resolution 1920 1080 # this is standard HD
fullscreen
scale
background color 128 128 128 # grey background
bitmapdir stimuli
set &&xpos 0 200 100 -100 -200 # for positioning in memory display
set &&ypos -170 -100 150 150 -100
#
set &&abstractBitmaps range 2 504 # we will refer to these bitmaps using their numbers
set &&concreteBitmaps range 505 1008 # we will refer to these bitmaps using their numbers
set &&trainingBitmaps range 1009 1018 # we will refer to these bitmaps using their numbers
#
# following are CIELAB color values for each degree of the color wheel (these are file rgbvalues.txt)
# there are exactly 360 lines, one color for each degree
set &&reds file rgbvalues.txt 2 # column 2 of file
set &&greens file rgbvalues.txt 3 # column 3 of file
set &&blues file rgbvalues.txt 4 # column 2 of file
#
set &showScores 1 # 0: do not show, 1: do show
include bitmaps.txt
svgs
feedback # used for creating feedback screen at end
## ---------------------------------------------------------------------------------------------
## "part" (sort of inline function) to draw connecting dots between two angles
## uses $tmpAngle1 , $tmpAngle2
part connectAngles
draw off
set $diffAngles1 expression $tmpAngle1 - $tmpAngle2
set $diffAngles2 expression $tmpAngle2 - $tmpAngle1
if $diffAngles1 >= 0 and $diffAngles1 <= 1800 # angle2 < angle1, so just go from angle 2 to angle1
for $i in $tmpAngle2 to $tmpAngle1 by 25
set &&tmpCoordinates circle 0 0 325 $i
show circle &&tmpCoordinates[1] &&tmpCoordinates[2] 3 black
for-end
fi
if $diffAngles2 >= 0 and $diffAngles2 <= 1800 # angle1 < angle2, so just go from angle 2 to angle1
for $i in $tmpAngle1 to $tmpAngle2 by 25
set &&tmpCoordinates circle 0 0 325 $i
show circle &&tmpCoordinates[1] &&tmpCoordinates[2] 3 black
for-end
fi
if $diffAngles1 >= 1800
set $tmpAngle2 increase 3600
for $i in $tmpAngle1 to $tmpAngle2 by 25
set &&tmpCoordinates circle 0 0 325 $i
show circle &&tmpCoordinates[1] &&tmpCoordinates[2] 3 black
for-end
fi
if $diffAngles2 >= 1800
set $tmpAngle1 increase 3600
for $i in $tmpAngle2 to $tmpAngle1 by 25
set &&tmpCoordinates circle 0 0 325 $i
show circle &&tmpCoordinates[1] &&tmpCoordinates[2] 3 black
for-end
fi
draw on
# -------------------------------------------------------------------------------------------------------------------------
task retrocue
set &trialCounter increase
## -- begin official trial ---------------------------------------
show bitmap fixpoint
delay 500
clear -1
## -- choose 5 random bitmaps (abstract or concrete) and put in &&myBitmaps
if &conditionAC = 0 # this is training
set &&myBitmaps sample &setSize from &&trainingBitmaps # this is a random sample of all available images (we will not remove them)
fi
if &conditionAC = 1 # this is concrete
set &&myBitmaps draw &setSize from &&concreteBitmaps # this is a random draw of all available images (they are removed once used)
fi
if &conditionAC = 2 # this is abstract
set &&myBitmaps draw &setSize from &&abstractBitmaps # this is a random draw of all available images (they are removed once used)
fi
## ---------------------------------------------------------------
## now choose one of &&myBitmaps and make that the target (the stimulus to respond to)
set &targetItem &&myBitmaps use random # this is the bitmap number
set &targetItemNum &&myBitmaps locate &targetItem ## needed for later matching with targetcolors
## -- now choose random colors from the CIELAB palet
# for the first color, we choose a value between 1 and 71, and then add 72 for next colors to make sure they are spread out
# &color1 etc are just indices on all the R/G/B values in the 359 item long palettes
set &&randomColors clear # for each stimulus in the &&myBitmaps you need a color, they need to be cleared each trial
set &colorDistance expression 360 / &setSize ## colors are spread out over a range, it must be 360 and not 3600 because colors are in arrays of 360 values
set &colorDistance round # we need to make sure this is rounded to a whole number (this might not be needed, need to check)
set &tmpColor random 1 &colorDistance # WHY THIS??? AH THAT SHOULD BE
for $i in 1 to &setSize
set &&randomColors append &tmpColor
set &tmpColor increase &colorDistance
for-end
set &&randomColors shuffle # this makes colors are not always in same place
#-- store the RGB of the target ------------------------------------------------------------------------------------
set &targetR &&reds[&&randomColors[&targetItemNum]] ## targetItemNum is value between 1 and &setSize
set &targetG &&greens[&&randomColors[&targetItemNum]]
set &targetB &&blues[&&randomColors[&targetItemNum]]
#-- memory display -------------------------------------------------------------------------------------------------
# to make sure the same sort of colors are not always on same position, we need to further sample those
# now apply the colors
set &&xpos clear ## this is just for storing xy positions
set &&ypos clear ## this is just for storing xy positions
set &&memDisplayStimuliNumbers clear # clear array that contains stimuli numbers, needed for clearing stimuli later
draw off # just draw without actually drawing on screen until all items are ready
if &conditionAC = 0
text align center
show text "Memorize color of each image" 0 -290
set &&memDisplayStimuliNumbers append SHOW_COUNTER
fi
set &angleCounter random 1 &colorDistance ## colorDistance is in angles (because color arrays have 360 values)
set &angleCounter expression &angleCounter * 10 # need to multiple x10 because we work with colors in arrays of 360 values
for &counter in 1 to &setSize
set &&xyPos circle 0 0 200 &angleCounter
set &&xpos append &&xyPos[1] # for later use (to show correct stimulus at end of trial)
set &&ypos append &&xyPos[2] # for later use (to show correct stimulus at end of trial)
# save &counter &angleCounter &&xyPos
show rectangle &&xyPos[1] &&xyPos[2] 147 147 &&reds[&&randomColors[&counter]] &&greens[&&randomColors[&counter]] &&blues[&&randomColors[&counter]] # 2
set &&memDisplayStimuliNumbers append SHOW_COUNTER
show bitmap &&myBitmaps[&counter] &&xyPos[1] &&xyPos[2]
set &&memDisplayStimuliNumbers append SHOW_COUNTER
set &angleCounter expression &angleCounter + &colorDistance * 10
for-end
draw on # now show everything you just added to the stimulus stack
#-------------------------------------------------------------------------------------------------------------------
delay &encoding_time ## encoding time is 1s, but during training1 it is 5 seconds
clear &&memDisplayStimuliNumbers # remove the items after showing. For testing or training, you can still show them
#-- now show cue in this task if needed
if &conditionCue = 1
show rectangle 0 0 &stimulus_width &stimulus_width white
show bitmap &targetItem
delay 250
clear -1 -2
delay 750
else
delay 1000
fi
##-- now show color wheel and test ------------------------------------------------------------------------------------
set &&memDisplayStimuliNumbers clear ## clear this again for next set of stimuli (for later clearing from screen)
set &rotationWheel random 0 3590 # rotate (tenths of degrees)
draw off
if &conditionAC = 0
text align center
show text "Move mouse over colors until" 0 -280
set &&memDisplayStimuliNumbers append SHOW_COUNTER
show text "it matches the color you remembered for this object." 0 -250
set &&memDisplayStimuliNumbers append SHOW_COUNTER
show text "When you are happy, click the mouse button." 0 -220
set &&memDisplayStimuliNumbers append SHOW_COUNTER
fi
rotate next &rotationWheel
show bitmap wheel ## with cue, this is stimulus #14, otherwise #12
set &stimulusCountWheel SHOW_COUNTER
show rectangle 0 0 &stimulus_width &stimulus_width black # start with black until people move mouse over color wheel (this is as in official experiment)
set &stimulusCountRect SHOW_COUNTER
show bitmap &targetItem
draw on
readmouse l &stimulusCountWheel 999999 range &stimulusCountWheel &stimulusCountWheel
hovercode begin
if MOUSE_R != 128 or MOUSE_G != 128 or MOUSE_B != 128 # update unless grey
update rectangle &stimulusCountRect 0 0 &stimulus_width &stimulus_width MOUSE_R MOUSE_G MOUSE_B
# now make copy of these colors (because sometimes if people click to choose outside colorwheel, these value would contain grey
set $chosenRed MOUSE_R
set $chosenGreen MOUSE_G
set $chosenBlue MOUSE_B
fi
hovercode end
if &conditionAC = 0 #only in training, now remove training help text
clear &&memDisplayStimuliNumbers
fi
##
## now we have had the response, and now we need to calculate score and give some feedback
##
## --- analyse results ------------------------------------------------------------------------------------------------
## participant clicked somewhere on color wheel and we know RGB, values. Now we need to find what the angle was exactly
## find the angle based on the target's colors (the correct angle) and then after that the users chosen angle
set &count 1 # this is a temporary counter for later match to the 360 RGB triplets
set &found 0 # this is just a help variable to check in the while loop if we found the RGB value
set &targetAngle -1 # set to -1, just to report if not angle was found
while &found = 0 and &count < 360
if &targetR = &&reds[&count] and &targetG = &&greens[&count] and &targetB = &&blues[&count]
set &found 1
set &targetAngle &count
fi
set &count increase
while-end
## find the angle of the chosen colors (based on the RGB values under mouseclick before)
set &count 1
set &found 0
set &chosenAngle -1 # set to -1, just to report if no angle was found
while &found = 0 && &count < 360
if $chosenRed = &&reds[&count] and $chosenGreen = &&greens[&count] and $chosenBlue = &&blues[&count]
set &found 1
set &chosenAngle &count
fi
set &count increase
while-end
## -- scoring ----------------------------------------------------------------------
set &diffScore1 expression abs ( &targetAngle - &chosenAngle ) ## the difference between the two angles
set &diffScore2 expression 360 - abs ( &targetAngle - &chosenAngle )
set &&tmpArray &diffScore1 &diffScore2
set &diffScore &&tmpArray min ## there are two possible scores, we need of course the smallest of the two; &diffScore is the actual score
## -- direct feedback --------------------------------------------------------------
## first we show the target item in the original set size (this is not per se necessary, but it is nice feedback) CHECK: IS THIS IN PAPER OR NOT?
show rectangle &&xpos[&targetItemNum] &&ypos[&targetItemNum] &stimulus_width &stimulus_width &targetR &targetG &targetB
show bitmap &targetItem &&xpos[&targetItemNum] &&ypos[&targetItemNum] ## show original item at original position
#
## next, we show arrow pointers where you clicked and where you should have clicked the wheel
#
## -- show angle as overlay, this is not in original study ----------------
if &chosenAngle >= 0 ## it can be less than zero if there was response
draw off
# 1. show arrows ("you" and "correct")
# 2. show dots connecting the two dots
# --- where you chose to click
set $tmpAngle1 expression &rotationWheel + &chosenAngle * 10
if $tmpAngle1 > 3600
set $tmpAngle1 decrease 3600
fi
if $tmpAngle1 < 1800 # depending on angle, the word is shown so it is convenient to read
rotate next $tmpAngle1
show bitmap overlayYouRight 0 0
else
rotate next $tmpAngle1
show bitmap overlayYouLeft 0 0
fi
# --- where original color was
set $tmpAngle2 expression &rotationWheel + &targetAngle * 10
if $tmpAngle2 > 3600
set $tmpAngle2 decrease 3600
fi
if $tmpAngle2 < 1800 # depending on angle, the word is shown so it is convenient to read
rotate next $tmpAngle2
show bitmap overlayCorrectRight 0 0
else
rotate next $tmpAngle2
show bitmap overlayCorrectLeft 0 0
fi
draw on
## --- now connecting dots ------------------------
part connectAngles ## this is just for nicer display, not in original, requires $tmpAngle1 and $tmpAngle2, which are positions on screen where clicked
fi
## ---------------------------------------------------------------
## next we write out the score in bottom right of screen
if &conditionAC = 0
show bitmap scoreExplained 650 0
fi
if &showScores = 1 # you can set this in "options"
set %trialCountFeedback "Trial number " &trialCounter " out of " &totalTrialsTodo
text align left
show text %trialCountFeedback 550 300 black
set %yourScore "Your score in this trial = " &diffScore
text align left
show text %yourScore 550 330 black
fi
text align left
show rectangle 715 420 350 60 yellow
show text "Click anywhere to continue" 550 420 black
## -- store feedback according to the 4 conditions for later task "feedback" at end of experiment
if &conditionAC = 1 and &conditionCue = 1
set &&scoresCoCue append &diffScore
fi
if &conditionAC = 1 and &conditionCue = 2
set &&scoresCoUnc append &diffScore
fi
if &conditionAC = 2 and &conditionCue = 1
set &&scoresAbCue append &diffScore
fi
if &conditionAC = 2 and &conditionCue = 2
set &&scoresAbUnc append &diffScore
fi
## -- keep data for error over moving window --------------------------------------------
set &&trackPerformance append &diffScore
set &trackPerformanceN &&trackPerformance size
if &trackPerformanceN > 4 ## if more than four, remove the oldest (i.e, first)
set &&trackPerformance remove first
set &trackPerformanceN &&trackPerformance size
fi
## -- determine set size for next trial if you have at least 4 trials --------------------
if &trackPerformanceN = 4
set &averageScoreWindow &&trackPerformance roundmean
if &averageScoreWindow < 40 and &setSize < 9
set &setSize increase
set &&trackPerformance clear
fi
if &averageScoreWindow > 40 and &setSize > 2
set &setSize decrease
set &&trackPerformance clear
fi
set %aws "Average score: " &averageScoreWindow # aws:average window score
fi
## -- report average score if needed, even if fewer than 4 trials
set &trackPerformanceN &&trackPerformance size
if &trackPerformanceN > 0 and &trackPerformanceN < 4
set &tmpAverageScoreWindow &&trackPerformance roundmean
set %aws "Average score: " &tmpAverageScoreWindow # aws:average window score
fi
if &showScores = 1
text align left
show text %aws 550 360 blue
fi
readmouse l 14 999999 ## there is no time limit for reading the feedback/scores
## -- if in training, make memorisation time slightly faster ----------------------------
if &conditionAC = 0
if &encoding_time > &encoding_timeNormal
set &encoding_time decrease 250 # reduce with 250 ms each trial, this would bring you to normal time in 8 trials, and there are 10 training trials
if &encoding_time < &encoding_timeNormal
set &encoding_time &encoding_timeNormal
fi
fi
fi
## -- end of task and save for datafile -------------------------------------------------
clear screen
save BLOCKNUMBER &setSize &conditionAC &conditionCue &rotationWheel &targetAngle &chosenAngle &diffScore RT &targetR &targetG &targetB $chosenRed $chosenGreen $chosenBlue
#------------------------------------------------------------------------------------------
# for feedback block we make fancy feedback screen
# we only call this one time at end of experiment
task showfeedback
## -- calculate scores -------------------------------
set &concreteCuedAvgScore &&scoresCoCue roundmean
set &concreteUncuedAvgScore &&scoresCoUnc roundmean
set &abstractCuedAvgScore &&scoresAbCue roundmean
set &abstractUncuedAvgScore &&scoresAbUnc roundmean
## -- render the scores to an SVG file ---------------
svg create myFeedback from feedback
svg replace "CO_CUE" &concreteCuedAvgScore
svg replace "CO_UNC" &concreteUncuedAvgScore
svg replace "AB_CUE" &abstractCuedAvgScore
svg replace "AB_UNC" &abstractUncuedAvgScore
svg render
delay 100
show bitmap myFeedback
readmouse l 1 9999999
#------------------------------------------------------------------------------------------
block screensize
message instructionFullScreen mouse
block trainingBlock
set &&trackPerformance clear # keeps data of moving window of 4 trials
set &encoding_time &encoding_timeTraining
set &setSize 3 # this is the starting setsize for training
message instructionTraining mouse
set &conditionAC 0 # 0: training
set &conditionCue 1 # 1: is cue, 2: no cue, we train with cue first
task retrocue 10
block concreteCued
# set &trialCounter 0 # after training, you can possibly set this back to 0
set &encoding_time &encoding_timeNormal
set &setSize 5 # this is the starting setsize
message instructionConcreteCued mouse
set &conditionAC 1 # 1: concrete, 2: abstract
set &conditionCue 1 # 1: is cue, 2: no cue
task retrocue 40
block concreteUncued
set &encoding_time &encoding_timeNormal
set &setSize 5 # this is the starting setsize
message instructionConcreteUncued mouse
set &conditionAC 1 # 1: concrete, 2: abstract
set &conditionCue 2 # 1: is cue, 2: no cue
task retrocue 40
block abstractCued
set &encoding_time &encoding_timeNormal
set &setSize 5 # this is the starting setsize
message instructionAbstractCued mouse
set &conditionAC 2 # 1: concrete, 2: abstract
set &conditionCue 1 # 1: is cue, 2: no cue
task retrocue 40
block abstractUncued
set &encoding_time &encoding_timeNormal
set &setSize 5 # this is the starting setsize
message instructionAbstractUncued mouse
set &conditionAC 2 # 1: concrete, 2: abstract
set &conditionCue 2 # 1: is cue, 2: no cue
task retrocue 40
block feedback
task showfeedback 1