Posner spatial cueing task: online demonstration

As mentioned in the related blog post, this is an online demonstration of the famous experiment in cognitive psychology on covert visual attention by Michael Posner and colleagues. It is implemented as a Java applet and the blog post discusses how to resolve possible security warnings to make it run (the app does not have a digital signature). If you have any comments, please use the comment field under that post. Below you can find more information on how to use it, what to try, as well as the whole source code.

Quick start:

The applet requires Java 5 or higher. Java must be enabled in your browser settings. Mac users must have Mac OS X 10.4 or higher. You may obtain the latest Java from Oracle's Java site.





powered by NetLogo

view/download model file: posner.nlogo

WHAT IS IT?

Posner’s spatial cueing task is a classic experiment in cognitive psychology. It shows how spatial cues (central or peripheral) shift covert visual attention, resulting in better performance in case of a valid cue (points to where the target will actually appear) than for invalid cues (points in the wrong direction). Trials without a cue can serve as a control (neutral) condition. For more information, see e.g. Wikipedia , APA website about this task, or some paper on this task by Michael Posner (see below).

Of course, this implementation is not meant for real testing purposes but mainly for education. Namely, the timing of events is highly imprecise.

HOW IT WORKS

Loop of infinite series of trials. Target boxes are displayed all the time. At the beginning of a trial a fixation cross appears. Subjects must fixate their eyes on this cross. After a short period of time* a cue can appear. It can be either valid or invalid with respect to the coming target, or absent. After another short period of time, called the stimulus onset asynchrony (SOA), the actual target appears in one of the two boxes. In this version of the experiment the subject must press either the left key or the right key according to where the target is, as fast as possible. A feedback (smily or sad face) will be given after each response.

*Based on the settings.

HOW TO USE IT

First, adjust the speed of the experiment using the slider on top of the main window, so that 1000 ticks correspond roughly to 1 second in real time. Use the button Start to test this.
Then you can prepare a new experiment using the button Setup. Use the SOA slider to set the duration between the presentation of the cue and of the target. Use the drop-down list to choose between a central or a peripheral cue. Use the sliders below to choose the ratio of trials having a certain cue validity.
You then start or pause the experiment with the Start button.
Use your keyboard to respond to stimuli. Press A if the target is in the left box and S if it is in the right box.
You should do a few dozens of trials so that your average results stabilize over time and are accurate enough.

THINGS TO NOTICE

THe usual result is that reaction times are fastest for valid trials than for neutral trials and the invalid trials are the slowest. This depends on the SOA, trial type ratio and on the cue type (central, peripheral, or symbolic). What results do you get if you experiment with these different settings?

THINGS TO TRY

Try to experiment with all the possible settings of SOA, cue type and trial type ratios. For instance, try to increase the ratio of valid trials to possibly observe bigger effects. E.g., if you use the symbolic cue, what is the difference between using a ratio of valid:invalid trials = 1:1 and using a ration 4:1? Do the results change as a result of prolonged experience?

EXTENDING THE MODEL

Check the psychological literature on Posner-type paradigms…
One could e.g. add a switch that would turn the neutral cue on or off. Without the neutral cue, the subject will have no arousing/target-onset predicting stimulus, which could influence performance on neutral trials.

NETLOGO FEATURES

An interesting feature of this model is that it is not actually a model or a simulation but an experiment dependent on the input from a person. There is a loop of events triggered by the number of ticks that have passed (see the code).

RELATED MODELS

I am not aware of any similar model.

CREDITS AND REFERENCES

Created by Ondrej Havlicek, 2014, ohavlicek [ a t ] gmail.com, www.ondrejhavlicek.com

Based on the work of Michael Posner and others.
Posner, M. I. (1980). Orienting of attention. The Quarterly journal of experimental psychology 32 (1): 3-25. doi:10.1080/00335558008248231. PMID 7367577

Creative Commons License
Posner spatial cueing task demonstration by Ondrej Havlicek is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
Based on a work at http://www.tandfonline.com/doi/abs/10.1080/00335558008248231.

CODE

breed [people person]
breed [targets target]
breed [cues cue]
breed [fixations fixation]
breed [feedbacks feedback]
breed [csymbols csymbol]
breed [tsymbols tsymbol]

cues-own [orientation]

globals
[
  speed
  triallength
  
  validlist
  invalidlist
  neutrallist
  
  vcorrect
  verrors
  icorrect
  ierrors
  ncorrect
  nerrors
  vrate
  irate
  nrate
  vmeanrt
  imeanrt
  nmeanrt
  
  rtime
  onsettick
  
  canrespond?
  targetpos
  trialtype
  
  sumratio
  dice
]



to reset
  __clear-all-and-reset-ticks  
  
  set canrespond? false
  set targetpos 0
  set trialtype 1

  set validlist []
  set invalidlist []
  set neutrallist []
  set vcorrect 0
  set verrors 0
  set icorrect 0
  set ierrors 0
  set ncorrect 0
  set nerrors 0

  set speed 1000
  set triallength 2000
  
  
  boxes blue
  
  
end


to go
  
  tick

  ;blank screen
  if (ticks mod triallength = 1) [
    update-monitors
    blank
    set canrespond? false
    boxes blue
    set targetpos ((random 2) + 1) ; 1 - 2
    
    set sumratio ratio-valid + ratio-invalid + ratio-neutral  ;1-valid, 2-invalid, 0-neutral
    set dice (random sumratio) + 1
    ifelse(dice <= ratio-valid) [
      set trialtype 1 ;valid
    ]
    [
      ifelse(dice > (ratio-valid + ratio-invalid)) 
      [set trialtype 0] ;neutral
      [set trialtype 2] ;invalid
    ]
    
  ]
  
  ;fixation cross
  if ((ticks - 500) mod triallength = 0) [paintfixation]
  
  ;cue
  if ((ticks - (1000 - SOA)) mod triallength = 0)
  [
    if(trialtype = 1)[
      ;valid
      ifelse(targetpos = 1) [leftcue] [rightcue]
    ]
    if(trialtype = 2)[
      ;invalid
      ifelse(targetpos = 2) [leftcue] [rightcue]
    ]
    if(trialtype = 0)[
      ;neutral
      neutralcue
    ]
  ]
  
  ;target
  if ((ticks - 1000) mod triallength = 0) [
    ifelse(targetpos = 1)[lefttarget] [righttarget]
    set onsettick ticks
    set canrespond? true
  ]
  
  
  
end


to setrt
  set rtime (ticks - onsettick)
end


to leftkey
  keypress 1
end

to rightkey
  keypress 2
end

to keypress [keyn]
  if(canrespond? = true)
  [
    set canrespond? false
    setrt
    ifelse(targetpos = keyn)
    ;correct response
    [
      setfeedback true
      ;valid
      if(trialtype = 1)[
        set validlist lput (rtime) validlist
        set vcorrect (vcorrect + 1)
      ]
      ;invalid
      if(trialtype = 2)[
        set invalidlist lput (rtime) invalidlist
        set icorrect (icorrect + 1)
      ]
      ;neutral
      if(trialtype = 0)[
        set neutrallist lput (rtime) neutrallist
        set ncorrect (ncorrect + 1)        
      ]

      update-plot
    ]
    ;wrong response
    [
      setfeedback false
      ;valid
      if(trialtype = 1)[
        set verrors (verrors + 1)
      ]
      ;invalid
      if(trialtype = 2)[
        set ierrors (ierrors + 1)
      ]
      if(trialtype = 0)[
        set nerrors (nerrors + 1)        
      ]
    ]
  ]
  
end




to paintfixation
  create-fixations 1 
  [
    setxy 0 0
    set size 1
    set shape "x"
    set color blue
    facexy 0 10
  ]
end

to leftcue
  setcue 1
end

to rightcue
  setcue 2
end

to setcue [side]
  ifelse(cuetype = "central")
  [
    create-cues 1
    [
      setxy 0 0
      set size 3
      set shape "default"
      set color green
      ifelse(side = 1) [facexy -10 0] [facexy 10 0]
    ]
  ]
  [ ;ifelse central else: peripheral or symbolic
  ifelse(cuetype = "peripheral")
  [
    ifelse(side = 1) [leftbox green] [rightbox green]
  ]
  ; symbolic
  [
    
    ifelse(side = 1)
    [  ;left cue
      ;create-csymbols 1
      create-cues 1
      [
        setxy 0 0
        set size 3
        set shape "pentagon"
        set color green
      ]
    ]
    [  ;right cue
      ;create-tsymbols 1
      create-cues 1
      [
        setxy 0 0
        set size 3
        set shape "triangle"
        set color green
      ]
    ]
    
  ]
  ]
end

to neutralcue
  ifelse(cuetype = "peripheral")
  [
    leftbox green
    rightbox green
  ]
  [ ;central or symbolic central
    create-cues 1
    [
      setxy 0 0
      set size 3
      set shape "dot"
      set color green
    ]
  ]
  
end


to lefttarget
  settarget 1
end

to righttarget
  settarget 2
end

to settarget [side]
  create-targets 1
  [
   ifelse(side = 1) [setxy -10 0] [setxy 10 0]
   set size 3
   set shape "star"
   set color yellow 
  ]
end


to setfeedback [correct?]
  create-feedbacks 1
  [
   setxy 0 -7
   set size 3
   ifelse(correct?) [set shape "face happy"] [set shape "face sad"]
   ifelse(correct?) [set color green] [set color red]
  ]
end



to blank
  ask fixations [die]
  ask cues [die]
  ask targets [die]
  ask feedbacks [die]
  ask csymbols [die]
  ask tsymbols [die]
  ;clear-turtles
end


to boxes [bcolor]
  ;ca                                              ;; clear everything
  leftbox bcolor
  rightbox bcolor
end
  
to leftbox [bcolor]  
  ;left box
  ask patches[
    ;; if patches are between (0,0) to (0,edge)...
    if ( pxcor = -13 and pycor >= -3 and pycor <= 3 )
      [set pcolor bcolor]                                 ;; ... draws left edge in red
    ;; if patches are between (edge,0) to (edge,edge)...
    if ( pxcor = -7 and pycor >= -3 and pycor <= 3 )
      [set pcolor bcolor]                                 ;; ... draws right edge in red
    ;; if patches are between (0,0) to (edge,0)...
    if ( pycor = -3 and pxcor >= -13 and pxcor <= -7 )
      [set pcolor bcolor]                                 ;; ... draws bottom edge in red
    ;; if patches are between (0,edge) to (edge,edge)...
    if ( pycor = 3 and pxcor >= -13 and pxcor <= -7 )
      [set pcolor bcolor]                                 ;; ... draws upper edge in red
    ]
end
  
to rightbox [bcolor]  
  ;rigth box
  ask patches[
    ;; if patches are between (0,0) to (0,edge)...
    if ( pxcor = 13 and pycor >= -3 and pycor <= 3 )
      [set pcolor bcolor]                                 ;; ... draws left edge in red
    ;; if patches are between (edge,0) to (edge,edge)...
    if ( pxcor = 7 and pycor >= -3 and pycor <= 3 )
      [set pcolor bcolor]                                 ;; ... draws right edge in red
    ;; if patches are between (0,0) to (edge,0)...
    if ( pycor = -3 and pxcor >= 7 and pxcor <= 13 )
      [set pcolor bcolor]                                 ;; ... draws bottom edge in red
    ;; if patches are between (0,edge) to (edge,edge)...
    if ( pycor = 3 and pxcor >= 7 and pxcor <= 13 )
      [set pcolor bcolor]                                 ;; ... draws upper edge in red
    ]
  
end


to update-monitors
  if((vcorrect + verrors) > 0) [
    set vrate (vcorrect / (vcorrect + verrors))
  ]
  if((icorrect + ierrors) > 0) [
    set irate (icorrect / (icorrect + ierrors))
  ]
  if((ncorrect + nerrors) > 0) [
    set nrate (ncorrect / (ncorrect + nerrors))
  ]
  
  if (length validlist > 0) [
    set vmeanrt mean validlist
  ]
  if (length invalidlist > 0) [
    set imeanrt mean invalidlist
  ]
  if (length neutrallist > 0) [
    set nmeanrt mean neutrallist
  ]
  
end


to update-plot
  set-current-plot "ReactionTime"
    set-current-plot-pen "valid"
    if (length validlist > 0) [
      plot mean validlist
    ]
    set-current-plot-pen "invalid"
    if (length invalidlist > 0) [
      plot mean invalidlist
    ]
    set-current-plot-pen "neutral"
    if (length neutrallist > 0) [
      plot mean neutrallist
    ]

  
end