| Reference | Downloads | Github

How to randomize presentation of stimuli in oddball experiment but make sure the oddball stimuli never appears at particular positions of trials

I have a conditions file that contains 8 stimuli: 7 standard auditory stimuli (which the subject is not to respond to) and 1 deviant/target auditory stimuli (which the subject should respond to with a button press). I would like to randomize the presentation of these 8 stimuli within a trial BUT the deviant/target stimuli must not appear in positions 1,2, or 8.

For example, presentation of stimuli in three consecutive trials could be as follows (where S is “standard” and D is “deviant”):
Trial 1: S S D S S S S S
Trial 2: S S S S S S D S
Trial 3: S S S S S D S S

Alternatively, the following patterns would NOT be allowed:

The only thing I can think of is to create conditions files that already specify the order of presentation with these parameters met. Which is to say that I would randomize the list of stimuli within a VERY LONG Excel file and then use PsychoPy to play it straight through…however, I would need to do this for over 800 trials, so I am hoping there is an easier way to approach this.

OS X El Capitan
PsychoPy version: v1.85.2

How do the S and D stimuli vary? i.e. are they constant (i.e. just two stimuli) or are there many possibilities for each?

Are they tones or audio files?

Depending on the answers, this may be easier to handle with a code snippet rather than with conditions files.

Hi Michael,

There are 7 choices for S (all of which must be used once) and 1 choice for D.

My current design has 4 conditions files (let’s call them C1, C2, C3, C4) that each contains 8 unique stimuli (7 standard and 1 deviant). These 8 stimuli make up one trial, and 100 trials make up a block. Each condition file contains the 8 stimuli for one block. The order of the blocks is randomized and each block is played fully before moving onto the next. For example, the C4 block might play its 100 trials followed by all the trials in C2, then C3, then C1.

They are audio files.

We really do need a precise description of your design before making the effort to suggest an implementation. The description is still ambiguous.

My interpretation is you have 32 different stimuli. These are divided into four unique sets of 8, each set being presented within one of four separate blocks. The only thing that varies across trials within a block is the order of stimuli. Standard stimuli can occur in any sequence within a trial from first to eighth stimulus. Deviant stimuli must only appear from third to seventh.

I would guess that the number of possible orders of such stimuli within a block would be much more than 100 so am also guessing that you would be happy with a random selection of the orders rather than some attempt at balancing the S stimuli?
But would you want balancing of the stimulus number in which the D stimulus occurs (i.e. 20 trials within each block at each of locations 3 through 7)?
Would these stimulus orders be randomly devised (possibly within constraints) for each subject or would they be constant for each subject?

Hopefully you can see that implementing a randomisation scheme in code requires a complete and unambiguous description of the requirements and constraints… There isn’t much point starting without it, as incorrect assumptions can change the code quite markedly.

Hi Michael,

Sorry for not being descriptive enough. Lucky, you are exactly correct in your interpretation of what I need to do. I never thought about balancing S explicitly (figured being “random” would take care of that enough)…but that’s a great idea! If that’s simple enough to implement, then yes, S should be balanced. The presentation order should be re-randomized for each subject.


I think there would be something like 5040 possible orders of seven S stimuli, so a random sample of them is probably OK. Would suggest that you do your randomisation in code rather than use a conditions file. e.g. insert a code component with Builder, and in its Begin Experiment tab, put something like this to define the lists of stimuli:

expt_standards = [['S01.wav', 'S02.wav', 'S03.wav', 'S04.wav', 
'S05.wav', 'S06.wav', 'S07.wav'],
['S08.wav', 'S09.wav', 'S10.wav', 'S11.wav', 'S12.wav', 'S13.wav', 'S14.wav'],
['S15.wav', 'S16.wav', 'S17.wav', 'S18.wav', 'S19.wav', 'S20.wav', 'S21.wav'],
['S22.wav', 'S23.wav', 'S24.wav', 'S25.wav', 'S26.wav', 'S27.wav', 'S28.wav']]

expt_deviants = ['D01.wav', 'D02.wav', 'D03.wav', 'D04.wav']

block_order = [0, 1, 2, 3]

Around your trial routine, you will need to have two loops, an inner one called trials (nReps = 100) and an outer one called blocks (nReps = 4).

You then need to select some stimuli. This happens once per block. You then need to randomise and shuffle the stimuli. This happens once per trial. So put code like this in the Begin routine tab of your code component:

if trials.thisN == 0: # only at the beginning of each block
    block_index = block_order.pop()
    block_standards = expt_standards[block_index] # get the next list
    block_deviant = expt_deviants[block_index] # keep the link between D and S
    thisExp.addData('block_index', block_index) # save it for posterity

trial_stimuli = list(block_standards) # make a copy of the current list
shuffle(trial_stimuli) # randomise the order of standard stimuli
# insert the deviant (NB 0-based, plus high = 1 more than the maximum):
trial_stimuli.insert(np.random.randint(low = 2, high = 7), block_deviant)
thisExp.addData('trial_stimuli', trial_stimuli) # could do it better than this

So now you have a randomised list of stimuli created for each trial, with fresh stimuli selected each block. The question is whether you actually need a third loop (i.e. a within-trial loop, nReps = 8) to cycle through these, or not, but will let you consider that.

1 Like