psychopy.org | Reference | Downloads | Github

Breaking two stimuli lists into short, alternating blocks

I am a beginner, and this should probably be easy for someone more experienced to answer; however, I don’t think this article exactly helps me, and I’m really unable to find a solution. Essentially, I will have two types of blocks (say A and B) that alternate, and there will be specific instructions to each type of block that precede them. There are a total of 6 trials/block, and each trial contains three images; each trial will be different (i.e. basically none of the images in any of the trials will repeat).

I have excel sheets with stimuli lists (Images 1, 2, and 3) for both types of blocks. The problem with the linked article (and the similar demo in psychopy) is that the house/face paradigm only has three total images, so each block goes through the whole stim list each time. What I need to do is, for example, for the first block, have Type A instructions, then rows 0-5 of my A stim list for six trials, followed by Type B instructions, then rows 0-5 of my B stim list, followed by Type A instructions and rows 6-11 of my A stim list, and so on.

If I can’t do this in the Builder view, that’s fine–and it would be helpful if someone could tell me that. But this seems like a pretty standard thing to do–what am I missing? If I use a paradigm like this:

01%20AM
I wouldn’t know how to stop the trials loop from cycling through all the trials before switching blocks. And obviously, I don’t want to make 9 smaller loops (5 Type A blocks, and 4 Type B blocks), but that’s the only way I can figure out right now.
Thank you so much–any help is very appreciated!

I’m not sure you’ve fully described your design constraints, but purely going from what you described above, I would suggest breaking up each of your current conditions files into two, each with 6 rows. Then the blocks conditions file for the outer loop would look like this:

instructions          conditions_file
Type A instructions   A1.csv
Type B instructions   B1.csv
Type A instructions   A2.csv
Type B instructions   B2.csv

Thanks very much for your reply. Hmm, which part of my explanation was unclear?
As I say towards the bottom, there will be 5 Type A blocks and 4 Type B blocks, so it seems like your solution would involve making 9 csv files (which I would have to randomize and re-make each time)?

The bit where the randomisation and ordering within and across tasks, images, and blocks and across sessions, and any counterbalancing needed, is not explicitly described.

Without that info though, there are two possible approaches:

  1. Do all of the randomisation and balancing in code at the start of each session, generating the conditions files you need. This would certainly be achievable but would need a precise description of your design and all of the levels of your variables (e.g. image names). And it would take a bit of work.
  2. It might be possible to do this with less code and just two fixed conditions files, by using much less code just to generate values for the selected rows field of your inner loop’s dialog. i.e. this would sample just 6 rows from the file, but need to keep track of them across blocks to avoid repetitions. There are some limitations in how Builder works with this field though, which unfortunately I can never remember, so it might not actually work exactly as needed for this particular design, but it might be the approach that would be best to try first.

e.g. for the second approach, try something like this. Insert a code component on the “readyMessage” routine. In its “begin experiment” tab, put something like this:

# create numbers corresponding to row indices of the two conditions files:
a_indices = list(range(5 * 6))
b_indices = list(range(4 * 6))

# randomise them per session:
shuffle(a_indices)
shuffle(b_indices)

Then in the “begin routine” tab, put something like this:

if blocks.thisN % 2 == 0: # on even-numbered blocks (including zeroth):
    conditions_file = 'A.csv'
    selected_rows = a_indices[-6:] # get six row numbers
    a_indices = a_indices[:-6] # remove them from further selection
else: # odd numbered blocks
    conditions_file = 'B.csv'
    selected_rows = b_indices[-6:]
    b_indices = b_indices[:-6]

Then the outer loop shouldn’t need to be connected to a conditions file at all, just give it an nReps of 9.

In the inner loop dialog, try putting $selected_rows in the selected rows field and $conditions_file in the Conditions field. The loop should be set to be sequential rather than random, or else it will break the random row selection we are applying.

I don’t know if this will work: let us know.

1 Like

You, sir, are a lifesaver! Thanks so much. To recap, my stim lists had already been randomized, counterbalanced, etc. in a separate R script I wrote (I’m new to Python). I used the technique you proposed (if even blocks, take from condition file A and A indices list, etc.) and used the same if/else statement for the specific instructions for each block.
Thanks again!

Ah, yes, that needed to happen if the outer loop wasn’t using a conditions file any more, I forgot about that. Glad this worked for you.

1 Like