psychopy.org | Reference | Downloads | Github

Randomly Select from Multiple Conditions files

randomization

#1

Hello All,

I have a task in which participants are presented with one image followed by another image. Fairly simple aside from the fact that I have 3 conditions files with these images that I would like to pseudo-randomly select from.

Here are examples of the 3 conditions files with a sample of their respective parameters:

threat1.csv
image1.jpg image2.jpg
image3.jpg image4.jpg
image5.jpg image6.jpg

threat2.csv
image1.jpg image7.jpg
image3.jpg image8.jpg
image5.jpg image9.jpg

neutral.csv
image10.jpg image11.jpg
image12.jpg image13.jpg
image14.jpg image15.jpg

The 2 threat files contain 40 images and the neutral condition contains 20 images. In total, the whole neutral file should be used and twenty from each threat file, for a total of 60 trials. These should be presented randomly. In addition, my threat files contain the same image for the first image presentation (see sample above), but the second image is different in each file. I would like for experiment to not ever have the same initial image presentation, so if image1.jpg is presented from threat1.csv, the program does not select image1.jpg from threat2.csv. I hope this makes sense.

I have attempted to use and modify code that I found on the old google forum to at least randomly select images to start (see below post). However, I received a few error codes, and it does not work.

I am hoping that someone may help me 1) get the code to work for a PC using Psychopy v1.83.00 and 2) modify it so that the presentation of threat images do not repeat. I am aware that the version of psychopy is a bit out dated, but we are running a study that was programmed on this version and have decided to not update until that study is complete.

Please let me know if additional information is needed and thank you!

Danielle

import csv
newConditions = [] #define an initially empty list
for fileName in ['Neutral.csv', 'Threat1.csv', 'Threat2.csv']:
    conditions = data.importConditions(fileName) #creat a list of dictionaries
    shuffle(conditions) #randomize their order
    conditions = conditions[0:20] #select just twenty of them
    newConditions.extend(conditions)
    #will end up as 60 randomly selected but balanced for consistency trials

#write out the conditions for this run of the experiment
header = newConditions[0].keys() # get the header labels as a list
    output = csv.DictWriter(file, fieldnames = header) #arrange to write our dictionaries to it
    output.writeheader()
    output.writerows(newConditions)```

#2

Hi @danta, it would help us to read the code if you surround your code with backticks.

I think a neater option would be to use Pandas to create your new condition file at the beginning of the experiment, and load it into trial handler in Builder for randomisation. In a code component, in the “Begin Experiment” tab:

import pandas as pd

fileName = ['neutral.csv', 'threat1.csv', 'threat2.csv']
conditionFile = pd.DataFrame(columns=['stim'])  # where 'stim' is the column name for your images

for files in fileName:
    myDat = pd.read_csv(files)  # Get conditions file 
    myDat = myDat.sample(frac=1).reset_index(drop=True)  # Shuffle the dataframe
    myDat = myDat.head(20)  # Take first 20 rows from sheet
    conditionFile = conditionFrame.append(myDat)  # Append to new conditions file variable

conditionFile.to_csv("myStim.csv")  # Save to new csv file for use in the loop handler.

#3

Thank you dvbridges!

I’ve adjusted my initial post and will be sure to follow this rule in the future! In the meantime, I will test your option and will provide updates on how this works. I truly appreciate your help.

Warmest Regards,
Danielle


#4

Hello Again @dvbridges,

I’ve had an opportunity to try this out. I am attaching the code that I used (modified with my parameters) Just to be clear there are two columns (image1, image2) in my data files as the image pairings are pre-determined.

I put this in a code component in my routine for the “begin experiment tab.”

import pandas as pd

fileName = ['Neutral.csv', 'Threat1.csv', 'Threat2.csv']
conditionFile = pd.DataFrame(columns=['image1','image2'])

for files in fileName:
    myDat = pd.read_csv(files) # get conditions file
    myDat = myDat.sample(frac=1).reset_index(drop=True) #shuffle the dataframe
    myDat = myDat.head(20) # take first 20 rows from sheet
    conditionFile = conditionFrame.append(myDat) #Append to new conditions file variable

conditionFile.to_csv("myStim.csv") #save to new csv file for use in the loop handler

I definitely receive far fewer errors. In fact, I received only one:

image

Unfortunately, I do not know how to remedy this, as I am quite the novice. Would you happen to know what the issue is?

Thank you!!
Danielle


#5

Ah yes thats my error, I changed the name of the conditionFile variable to make it more readable and missed one. Just change conditionFrame to conditionFile.


#6

Thank you!

It looks like I’m getting close here. I’ve now received this error message:

I’ve double checked my own conditions files to make sure there are no punctuations, spaces, or other wise in the headers, and this appears to be the case.
I did notice that in the myStim.csv a new parameter has been added to the first column (the order of presentation). Essentially it counts from 0 to 19 for each stimulus pulled from each file. This column does not have a header, and I wonder if it is being read in as a space.

I have attempted a few solutions, none of which have worked. Is there a way to fix this? Or perhaps what I think is the problem is not actually the problem. :exploding_head:

Thank you for all your assistance,
Danielle


#7

Have you tried this help article? Perhaps you could create a second .psyexp file, follow the directions in the link, and then copy and paste the code over to your first experiment. The last section, especially the last paragraph, should be helpful.


#8

Hello @jstruck,

Thank you for your assistance! I have actually seen this article and programmed an experiment in this way before. My problem however, is that I do not want blocks of a particular image type, but moreover to scramble a sub-set of images from each file of image types, and present the images randomly for each participant. so each block can have each type of image.

Unless I am misunderstanding that article, I do not think that method will apply here.

Thank you!
Danielle


#9

Hi Danielle,

I’m sorry, I misunderstood your question. I’m no good with Python, but I’m still thinking through ways it could be conceptualized. What if you select the neutral file in full, and then select random rows from a condition file? Maybe you could generate a list of twenty integers between 1 and 40 (without replacement, of course), and then assign this list to the row selection option (it’s in the builder view, so I assume it’s easily to code). I apologize if that’s too abstract or not useful enough at this point, but since I’m already here I might as well give my two cents.

Best,
Jason


#10

Simply give that column a header. PsychoPy can’t make sense of importing a file full of variables if one or more of those variables is not named.


#11

Hi @danta. in your code, change the code that saves the new csv to:

conditionFile.to_csv("myFile.csv", index=False)   # Where index=False will remove the index column with no header