psychopy.org | Reference | Downloads | Github

Dynamically changing step sizes in a staircase method

Hi all!

I work on a double staircase experiment and I would like to change the step size in real-time adjusting it as a rate of the initial intensity and according to the previous participants replies. For that, i need to pick
stepSizes parameter which belongs to StairHandler and change it each time.
In the below code for instance, in the nested for-loop, why when doing thisStair.stepSizes=0.5 and right after that thisIntensity = next(thisStair) it seems like the staircase proceeds with the initial stepSize, which is 1set at the the first for-loop, and not with 0.5?

I would really appreciate your comments.

Thank you in advance

    from __future__ import print_function
    from builtins import next
    from builtins import range
    from psychopy import visual, core, data, event
    from numpy.random import shuffle
    import copy, time  # from the std python libs
    
    # create some info to store with the data
    info = {}
    info['startPoints'] = [10, 20]
    info['nTrials'] = 10
    info['observer'] = 'jwp'
    info['stepSizes'] = 1
    info['maxValues'] = [info['startPoints'][0],info['startPoints'][1]]
    
    win = visual.Window([400, 400])
    # ---------------------
    # create the stimuli
    # ---------------------
    
    # create staircases
    stairs = []
    for thisStart in range(len(info['startPoints'])):
        # we need a COPY of the info for each staircase
        # (or the changes here will be made to all the other staircases)
        thisInfo = copy.copy(info)
        # now add any specific info for this staircase
        thisInfo['thisStart'] = info['startPoints'][thisStart]  # we might want to keep track of this
        thisStair = data.StairHandler(startVal=thisInfo['thisStart'],
                                      stepSizes=info['stepSizes'],
                                      nTrials=10, nUp=1, nDown=1,
                                      applyInitialRule=False,
                                      extraInfo=thisInfo,
                                      stepType='lin',
                                      minVal=0.5, maxVal=info['maxValues'][thisStart]
                                      )
        stairs.append(thisStair)
    
    
    for trialN in range(info['nTrials']):
        shuffle(stairs)  # this shuffles 'in place' (ie stairs itself is changed, nothing returned)
        # then loop through our randomised order of staircases for this repeat
    
        for thisStair in stairs:
            print(thisStair.reversalIntensities)
            print(thisStair.currentDirection)
            # print(thisStair.intensities)
            thisStair.stepSizes
            thisIntensity = next(thisStair)
            print('start=%.2f, current=%.4f' % (thisStair.extraInfo['thisStart'], thisStair.intensities))
            print("-----------------")
            # ---------------------
            # run your trial and get an input
            # ---------------------
            keys = event.waitKeys()  # (we can simulate by pushing left for 'correct')
            if 'left' in keys:
                wasCorrect = True
            else:
                wasCorrect = False
    
            thisStair.addResponse(wasCorrect)  # so that the staircase adjusts itself

I think this is because there’s a lot which happens when you create a StairHandler to make the staircase step happen, this uses the value set on creation - so just changing the step size won’t necessarily change that. You could try creating thisStair in the for trialN loop, this will affect timing as you’re initialising an object each iteration of the loop, but it may not be by much.