Last chance! 50% off unlimited learning
Sale ends in
fourTwo is a 4-2 dB staircase beginning at level est
terminating
after two reversals.
The final estimate is the average of the last two presentations.
It also terminates if the minStimulus
is not seen twice, or
the maxStimulus
is seen twice.
fourTwo.start(est=25, instRange=c(0,40), verbose=FALSE, makeStim, ...)
fourTwo.step(state, nextStim=NULL)
fourTwo.stop(state)
fourTwo.final(state)
Starting estimate in dB
Dynamic range of the instrument c(min,max) in dB
True if you want each presentation printed
A function that takes a dB value and numPresentations and returns an OPI datatype ready for passing to opiPresent
Extra parameters to pass to the opiPresent function
Current state of the fourTwo returned by fourTwo.start
and fourTwo.step
.
A valid object for opiPresent
to use as its nextStim
.
fourTwo.start
returns a list that can be passed to
fourTwo.step
,
fourTwo.stop
and
fourTwo.final
. It represents the state of a fourTwo
at a single location at a point in time and
contains the following.
name: fourTwo
A copy of all of the parameters supplied to fourTwo.start:
startingEstimate=est
,
minStimulus=instRange[1]
,
maxStimulus=instRange[2]
,
makeStim
, and
opiParams=list(...)
.
currentLevel: The next stimulus to present.
lastSeen: The last seen stimulus.
lastResponse: The last response given.
stairResult: The final result if finished (initially NA
).
finished: "Not"
if staircae has not finished, or one of
"Rev"
(finished due to 2 reversas),
"Max"
(finished due to 2 maxStimulus
seen),
"Min"
(finished due to 2 minStimulus
not seen).
numberOfReversals: Number of reversals so far.
currSeenLimit: Number of times maxStimulus
has been seen.
currNotSeenLimit: Number of times minStimulus
not seen.
numPresentations: Number of presentations so far.
stimuli: Vector of stimuli shown at each call to fourTwo.step
.
responses: Vector of responses received (1 seen, 0 not) receieved at each call to fourTwo.step
.
responseTimes: Vector of response times receieved at each call to fourTwo.step
.
fourTwo.step
returns a list containing
state: The new state after presenting a stimuli and getting a response.
resp: The return from the opiPresent
call that was made.
fourTwo.stop
returns TRUE
if the staircase is finished (2 reversals, or maxStimulus
is seen twice or
minStimulus
is not seen twice).
fourTwo.final
returns the final estimate of threshold (mena of last
two reversals). This issues a warning if called before the staircase has
finished, but still returns a value.
This is an implementation of a 4-2 1-up 1-down staircase.
The initial
staircase starts at est
and proceeds in steps of 4dB
until the first reversal, and 2dB until the next reversal.
The mean of the last two presentations is taken as the threshold value.
Note this function will repeatedly call opiPresent
for a stimulus
until opiPresent
returns NULL
(ie no error occured).
If more than one fourTwo is to be interleaved (for example, testing multiple locations), then the
fourTwo.start
, fourTwo.step
, fourTwo.stop
and fourTwo.final
calls can maintain the state of
the fourTwo after each presentation, and should be used.
See examples below.
Please cite: A. Turpin, P.H. Artes and A.M. McKendrick "The Open Perimetry Interface: An enabling tool for clinical visual psychophysics", Journal of Vision 12(11) 2012.
http://perimetry.org/OPI
# NOT RUN {
# Stimulus is Size III white-on-white as in the HFA
makeStim <- function(db, n) {
s <- list(x=9, y=9, level=dbTocd(db), size=0.43, color="white",
duration=200, responseWindow=1500)
class(s) <- "opiStaticStimulus"
return(s)
}
chooseOpi("SimHenson")
if (!is.null(opiInitialize(type="C", cap=6)))
stop("opiInitialize failed")
##############################################
# This section is for multiple fourTwos
##############################################
makeStimHelper <- function(db,n, x, y) { # returns a function of (db,n)
ff <- function(db, n) db+n
body(ff) <- substitute(
{s <- list(x=x, y=y, level=dbTocd(db), size=0.43, color="white",
duration=200, responseWindow=1500)
class(s) <- "opiStaticStimulus"
return(s)
}
, list(x=x,y=y))
return(ff)
}
# List of (x, y, true threshold) triples
locations <- list(c(9,9,30), c(-9,-9,32), c(9,-9,31), c(-9,9,33))
# Setup starting states for each location
states <- lapply(locations, function(loc) {
fourTwo.start( makeStim=makeStimHelper(db,n,loc[1],loc[2]),
tt=loc[3], fpr=0.03, fnr=0.01)
})
# Loop through until all states are "stop"
while(!all(st <- unlist(lapply(states, fourTwo.stop)))) {
i <- which(!st) # choose a random,
i <- i[runif(1, min=1, max=length(i))] # unstopped state
r <- fourTwo.step(states[[i]]) # step it
states[[i]] <- r$state # update the states
}
finals <- lapply(states, fourTwo.final) # get final estimates of threshold
for(i in 1:length(locations)) {
cat(sprintf("Location (%+2d,%+2d) ",locations[[i]][1], locations[[i]][2]))
cat(sprintf("has threshold %4.2f\n", finals[[i]]))
}
if (!is.null(opiClose()))
warning("opiClose() failed")
# }
Run the code above in your browser using DataLab