addOtherData not saved with multistairhandler + questplushandler

Hi,
I attempt to have several loops interleaved using a MultiStairHandler and save the data to a csv file using the ExperimentHandler. The loops themselves are of type QuestPlusHandler. In addition, I want to save other data for each trial, added using MultiStairHandler.addOtherData. However, the other data is not saved in the csv file. When not using the MultiStairHandler and simply adding several QuestPlusHandlers to an ExperimentHandler, other data is saved without a problem.

  • An example for other data not saved with MultiStairHandler:
from psychopy import data

intensities = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
thresholds = [0.5, 0.6, 0.7]
slopes = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
lowerAsymptoteVals = [0]
lapseRateVals = [0]
common_conds = {'intensityVals': intensities, 'thresholdVals': thresholds, 'slopeVals': slopes,
                'lowerAsymptoteVals': lowerAsymptoteVals, 'lapseRateVals': lapseRateVals,
                'responseVals': ['correct', 'incorrect']}
conds = [{**common_conds, 'startIntensity': 1, 'label': 'one'}, {**common_conds, 'startIntensity': 10, 'label': 'ten'}]
stairs = data.MultiStairHandler(stairType='questplus', method='random', conditions=conds, nTrials=20)
exp = data.ExperimentHandler(name='test_multi', dataFileName='test_multi')
exp.addLoop(stairs)
for ii, (this_int, this_cond) in enumerate(stairs):
    print(ii**2)
    stairs.addResponse('incorrect')
    stairs.addOtherData('otherData', ii**2)
    exp.nextEntry()
exp.close()

and the output file:
test_multi.csv (6.5 KB)
Note that there is no otherData column in the output file.

  • An example for other data saved when not using MultiStairHandler:
from psychopy import data

intensities = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
thresholds = [0.5, 0.6, 0.7]
slopes = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
lowerAsymptoteVals = [0]
lapseRateVals = [0]
common_conds = {'intensityVals': intensities, 'thresholdVals': thresholds, 'slopeVals': slopes,
                'lowerAsymptoteVals': lowerAsymptoteVals, 'lapseRateVals': lapseRateVals,
                'responseVals': ['correct', 'incorrect']}
conds = [{**common_conds, 'startIntensity': 1, 'label': 'one'}, {**common_conds, 'startIntensity': 10, 'label': 'ten'}]
stair1 = data.QuestPlusHandler(nTrials=20, **conds[0])
stair2 = data.QuestPlusHandler(nTrials=20, **conds[1])
stairs = [stair1, stair2]
# stairs = data.MultiStairHandler(stairType='questplus', method='random', conditions=conds, nTrials=20)
exp = data.ExperimentHandler(name='test', dataFileName='test')
for stair in stairs:
    exp.addLoop(stair)
    for ii in range(20):
        this_int = stair.next()
        stair.addOtherData('otherData', ii**2)
        stair.addResponse('incorrect')
        exp.nextEntry()
exp.close()

Output file:
test_seq.csv (1010 Bytes)
Note that there is a column otherData, which wasn’t in the MultiStairHandler case.
Also note that in the first case, ExperimentHandler saves a lot of data I don’t need - the .intensityVals, .thresholdVals, etc used to define the QuestPlusHandler. Is there a way to not save this data?

I appreciate your help in the matter!

Edit: I see I accidentally gave examples with different order of stair.addOtherData and stair.addResponse; however, I tried it both ways and it doesn’t matter.

Edit 2: I tried calling the addOtherData method of the QuestPlusHandler directly using stairs.currentStaircase.addOtherData(...) and it still didn’t work.

Edit 3: I did a little digging and found out the cause for the bug. MultiStairHandler.addOtherData(...) calls QuestPlusHandler.addOtherData internally, which is called correctly. However, it attempts to add the data to the ExperimentHandler and fails, in the following piece of code in staircase.py:

        if self.getExp() != None:  # update the experiment handler too
            self.getExp().addData(dataName, value)

.getExp returns None, possibly since it was registered to the ExperimentHandler indirectly using the MultiStairHandler, which doesn’t register the individual sub-handlers.