psychopy.org | Reference | Downloads | Github

Random stimulus draws from two lists alternating in a sequential pattern

Win10
PsychoPy v3.2.4

In the experiment I am trying to program, each participant will see 30 trials containing either “Type A” or “Type B” images. The sequence in which these “A” and “B” trials occur is fixed and should be the same for all participants, e.g.: A, B, A, A, B, A, B, B […]

For A trials, an image should be randomly drawn (without replacement throughout the experiment) from a folder containing A images, the same applies for B trials and a pool of B images.

I tried to solve this with two nested loops and three condition files: First I created a cond.csv file that looks like this:

sheets
A.csv
B.csv
A.csv
A.csv
B.csv
A.csv
B.csv
B.csv
[…]

The A.csv and B.csv each look like this with the path adjusted to A or B:

imagestim
A/img1.PNG
A/img2.PNG
A/img3.PNG
[…]

The outer loop is set to sequential and refers to the cond.csv file (so I would expect it to iterate through this list), the second loop is set to random and refers to $sheets instead of a file. Then, a routine which contains an image stimulus refers to $imagestim to present the images.The Variable nReps is set to 1 for both loops.

When I run this, each file listing images is looped through entirely before exiting the inner loop and moving on to the outer loop again. However, what I want is a random pick of just 1 stimulus from one of the two lists, depending on the position of the outer loop. Can this be done in the builder or should I change it in the code directly?

Any help is appreciated!

Can you clarify how many trials and images there are? From the above, one might guess 30 trials in total, with 15 A-type images and 15 B-type images to select from?

Thank you for the quick reply, I hope this clarifies it:

Each Participant should go through 30 trials in total, 15 A-Type and 15 B-Type. The A-Type and B-Type pool contain 15 images each. This means every participant should see every image but not necessarily in the same trial (e.g., Participant 1 could see any A-type image from the pool in trial 1 but should never be presented a B-type image for this particular trial in the sequence).

Edit - To clarify further: The drawing of A-Type or B-Type images should be random without replacement, so if we assume that trial 30 is also an A-Trial, it should present the last A-type image from the pool that was not previously presented.

Insert a code component (from the “custom” component panel). In its “Begin experiment” tab, put something like this:

# define image lists:
A_images = [f'A/img{i}.png' for i in range (1,16)]
shuffle(A_images) # randomise the order

B_images = [f'B/img{i}.png' for i in range (1,16)]
shuffle(B_images)

In your image component, put a variable name like $current_image in the “image” field, and then update it on each trial by putting something like this in the “Begin routine” tab of the code component:

if trial_type == 'A':
    current_image = A_images.pop() # removes from list, so can't be selected again
else:
    current_image = B_images.pop()

# record it in the data file:
thisExp.addData('image_name', current_image)

i.e. I’m assuming that your conditions file has a column called trial_type containing A or B values. Amend as required.

Also ensure that the code component is placed above the image component, so that the latter gets the current value of current_image.

1 Like

Thank you very much for your swift support, this solution worked like a charm!

Note to anyone attempting to recreate a similar experiment: This solution needs only one loop and one conditions file (instead of two) in the builder (containing the trial_type variable with values of “A” and “B” mentioned in the solution). Also, the $current_image variable must be set to “set every repeat” in the image component.