Staircase handler stepSizes parameter - what are the possibilities?

Hi,
I am trying to write a staircase for a visual perception task. From a previous task I will have calculated a participants particular ‘threshold value’/just noticeable difference value (e.g 40ms), and I am trying to write a programme where I can input the participants threshold value at the start, and then the stair case goes up/down in increments of this threshold (e.g every step up could be 2xthreshold value, and steps down could by 1xthreshold). (I know this probably sounds like a weird request from a psychophysics point of view since I already know their threshold (!), but the reason is I want to utilise a long staircase as a ‘training’ condition to try and improve task performance) Currently my staircase looks like this:

#create the staircase handler
staircase = data.StairHandler(startVal = 15,
stepType = ‘lin’, stepSizes=[3,1],
minVal=1, maxVal=30,
nUp=1, nDown=1, #will home in on the 80% threshold
nTrials=30, nReversals=4)

I would be grateful for suggestions of what code could be written for the stepSizes parameter that would enable the staircase to go up/down in multiples of the participants’ individual threshold values. My python skills are pretty basic.
Thanks! Christina

Hi there,

As far as I'm aware, the best way of doing this would be to change the step size on each trial. The stepSizes parameter is treated as symmetrical by the Staircase handler.

So assuming you have the threshold in a variable called threshold, you could try this:

for difficulty in staircase:
     correct = trialFunction(difficulty)  # this should be whatever your trial is and return either 1 or 0

     if correct:
          staircase.stepsize=2*threshold
     else:
          staircase.stepsize=threshold

     staircase.addData(correct)


(Apologies if the formatting is bad as I'm writing from my phone)

Best

Jan

Yes, as Jan says the step size is designed to be equal in the two directions. Normally you vary the number of correct/incorrect and then move a consistent step size rather than varying the size of the step.
Also, if you’re wanting a long run you probably need to extend the number of reversals. In your code once the participant has changed direction 4 times the staircase will terminate (I think).

Although I think there’s a good case to be made for psychopy to include unequal stepsizes, since it is quite a common way to do a staircase and is quite flexible… as mentioned in this issue:

Thank you very much everyone for all your tips - it will probably take me a few days to implement them, but I shall report back soon…
Christina

Hi Jan,

I am experimenting with putting the code you suggested into the staircase just now, but please could you explain a little more about
correct = trialFunction(difficulty)?
Psychopy is telling me I have not defined ‘trialFunction’ so I am wondering what else I need to write to define this early in the programme?

Thanks for your help!
Christina

Hi Christina,

sure - sorry about leaving it a bit confusing. I put the trialFunction in there as a placeholder. I would imagine that in your experiment, you have a loop somewhere in which you:

  • present stimuli, either visual or sound
  • collect the subject’s response
  • check if the response was correct or false

This should go either either into a function that you define (which I called trialFunction here) or inside the loop. So for example it could look like this:

for duration in staircase:
     stimulus.draw()  # draw stimulus
     win.flip()  # display stimulus
     core.wait(duration)  # wait for however long you need to
     win.flip()  # remove the stimulus from screen
     response = event.waitKeys()  # wait for the response
     if rightChoice in response:
          correct = 1  # set correct true
     else:
          correct = 0  # set correct false

     if correct:
          staircase.stepsize=2*threshold
     else:
          staircase.stepsize=threshold

     staircase.addData(correct)

But this is just an example! Ultimately, you just need to run your trial and make sure correct is either set to 1 or 0 depending on if they got it right or wrong for this code to work. Just replace whatever you were doing beforehand with the bit that includes trialFunction.

Hope that makes sense.

BW,
Jan

1 Like

Thanks Jan! That makes perfect sense now.:slight_smile:

Hi everyone, I enter this conversation because I cannot assign a minimum and a maximum value to my staircase. I state that I created a manual staircase not using the dedicated function. Specifically, I attributed an initial start value to my target stimulus and this value changes according to the response and the previous target.

StimulusStart = 10
LastStimulus = StimulusStart

if resp.corr:
StimulusStart = LastStimulus + 1

if not resp.corr:
StimulusStart = LastStimulus - 2

Fortunately it works as it should but I would like the presentation of the stimulus (StimulusStart) can reach a minimum value of 5 and a maximum value of 15.

I tried to use minVal = 5 and maxVal = 15 but it doesn’t work.
How can I do?

I hope in your help,

thank you in advance

I’m not sure the solutions presented above actually work, I am getting the same issues as here: Dynamically changing step sizes in a staircase method

from psychopy import data, event
import random
staircase = data.StairHandler(startVal=50, stepType='lin', stepSizes = 10, nUp=1, nDown=2, nTrials=10)

trial = 0
for thisTrial in staircase:
    if trial > 2:
        staircase.stepSizes = 1
    print(thisTrial)
    if random.random() > 0.5:
        staircase.addData(1)
    else:
        staircase.addData(0)
    trial +=1

although interestingly, calling print(staircase.stepSizes) indicates the value is being changed, although as the person replying in the post linked above states, the knock-on effects of initialising with this value don’t carry over.

If anyone does have a solution, I’d love to hear it! for now I may have to hard code in my own staircase :weary:

Edit: found some sort of solution here: stairHandler step size change based on trial number/ dynamic step sizes