I am trying to build an experiment in which I have something like the following:
# Open experiment handler
experiment = data.ExperimentHandler(name=expInfo["Experiment"], version='',
extraInfo=expInfo, runtimeInfo=None,
originPath=None,
savePickle=True, saveWideText=True,
dataFileName=expInfo["DataFile"])
# Open trial handler
trials = data.TrialHandler(nReps=expInfo["NumRepetitions"], method='random',
extraInfo=expInfo, originPath=-1,
trialList=data.importConditions(expInfo["FileConditions"]),
seed=None, name='trials')
experiment.addLoop(trials)
# Loop trials
for trial in trials:
# Do stuff
...
# If something happened (e.g., participant gave wrong response), redo trial a while later
trials.trialList.append(trial)
Especially the part trials.trialList.append(trial), is this possible, and is it save? I guess it is possible, though it is not save, as fields like trials.nTotal and such do not get updated.
So, would this at all work, is there already a working solution around this ‘problem’, or is it an idea to be able to do something like trials.insertTrial(trial, index=2), which means that the trial gets inserted 2 trials later from now in the trialList, and all other fields in trials get updated too, so everything keeps working as is.
The trialList is just a parameter used in the initial creation of a TrialHandler. The TrialHandler then parses that list of values into a set of Trial objects. So appending something to trialList won’t have any effect once the TrialHandler has already been instantiated. It also doesn’t make any sense to append Trial objects to the trialList, as it doesn’t actual contain Trial objects (the TrialHandler does).
Unfortunately, as far as I know, the TrialHandler class doesn’t really support being modified after creation. You could try sub-classing it to add this functionality, but as you note, you’d need to take care of a lot of things like updating its various other attributes, and you’d need to understand the class inside and out to make sure that the functionality doesn’t break in unforeseen ways.
I guess a way to think about this would be “how would I do this using the Builder approach?”
We can implement repeating trials there by wrapping a routine inside two loops: the outer one linked to the conditions file, and an inner which runs each trial as many times as needed. But that wouldn’t handle what you want, of not immediately repeating a trial, but doing so sometime later.
So sorry, I don’t have much to offer here, except that you might need to hand-roll your own solution.
Sounds fair. So indeed, I do not want to redo the trial immediately, participants will notice and all kinds of priming effect will be gained/lost. It does sound like a neat feature to have, so I will play around building a superclass of TrialHandler.
I’ve just been thinking about this, because I’ve run into the same problem, and what might work as a little workaround is to keep a list of all trials you want to redo, and at the end of your initial TrialHandler you create a new TrialHandler with only that list and run through them again.
Feel free to contact me if you want to look at a nice neat implementation of this.
What I did was very specific to my experiment, so it’s kind of difficult to explain. As I mentioned in my post, you could keep a list of all the trials you would like to redo, and at the end of your initial set of trials you can create a new trialHandler to run these specific trials again. This does mean that you would only repeat them once, so if your participants get it wrong again, you either move on, or repeat the process (which you might not want to do).
I always use .xlsx files for my conditions and import them using data.importConditions(). You could build a new .xlsx file from all failed/missed trials during the experiment. After running all the trials, you can then check whether this new file has any lines, import it into a new trialHandler, and repeat the experiment with only those trials…