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