I work on Win 10, PsychoPy v2021.2.3 standard standalone version
I am trying to randomize trials.
I have a csv file (MMN_stim.csv) containing my stim and trigger’s info (it will be an EEG study).
So I have:
- 1030 lines for the sound
standard.wav
- 100 lines for the sound
deviant_1.wav
- 100 lines for the sound
deviant_2.wav
- 100 lines for the sound
deviant_3.wav
- 100 lines for the sound
deviant_4.wav
The csv file looks like
stim trigger_1 trigger_2 time_trigger_1 time_trigger_2
sound_file.wav 1 2 0.1 0.6
I would like to randomise my list by making sure that a deviant stim will never be immediately followed by another deviant. In other words, each deviant stim must always be immediately followed by a standard stim.
Below is the code I inserted in my first routine:
filename_to_read = _thisDir + os.sep + 'MMN_stim.csv'
filename_to_write = _thisDir + os.sep + 'MMN_stim_B1_random.csv'
doubledev = False
listok = False
my_file = open(filename_to_read)
randstim = my_file.readlines()
header, stim_list = randstim[0], randstim[1:]
shuffle(stim_list)
while listok == False:
for i in range(len(stim_list)-1):
if (stim_list[i,0] != 'standard.wav') and (stim_list[i+1,0] != 'standard.wav'):
doubledev = True
break
if doubledev == True:
shuffle(stim_list)
print("reshuffle ...")
doubledev = False
else:
listok = True
with open(filename_to_write,'w') as out:
out.write(''.join([header]+stim_list))
However, the script keeps running without ending (even after 1 or 2 minutes) and I can’t figure out why. The text component of my first routine never shows up so I guess psychopy is running the while loop again and again, but the message "reshuffle ..."
is never printed.
When I remove the while loop, everything is working fine but there is systematically consecutive deviant sounds.
Any advice would be greatly appreciated!!
Thanks in advance,
Ambre
The way I do this with prospective memory targets is have a jittered gap. You can see my PM code on Pavlovia which is similar my independent randomisation demo. I preload the stimuli into lists and then present them in a loop with no spreadsheet.
1 Like
Many thanks for your reply. Just to be sure, is that the correct link of the experiment you mentioned: VESPR / PM Time · GitLab?
Indeed I don’t really need to write the randomized list, and as I have only 4 different stim I could easily write a code to determine triggers
and triggers_times
. However I already tried to do it without any spreadsheet (see code bellow) but it still does not work. I’m stucked at the very beginning of the experiment. That is I can launch the experiment, enter the participant number, and then nothing happens, I don’t stop seeing the blank grey screen.
This is due to the while loop and does not come from problems about playing stimuli. But I’m fully unable to figure out what’s wrong as I do not have any error message.
I did not see any conditional randomization in your code, could you tell me if you have one and if so in which routine it is?
Bellow is the code creating the stimuli list without spreadsheet:
stim_list = ['standard.wav']*1030 + ['deviant_1.wav', 'deviant_2.wav', 'deviant_3.wav', 'deviant_4.wav']*100
shuffle(stim_list)
doubledev = False
list_ok = False
while list_ok == False:
for i in range(len(stim_list) - 1):
if (stim_list[i] != 'standard.wav') and (stim_list[i+1] != 'standard.wav'):
doubledev = True
break
if doubledev == True:
shuffle(stim_list)
print("reshuffle ...")
doubledev = False
else:
list_ok = True
That’s the correct demo.
The spreadsheet has Words and Targets (equivalent to your standard and deviant trials).
The words are loaded into wordlist (in the word_loop loop)
The targets are loaded into targetlist (in the targets loop)
targetgap is set to 25 in the code component in the start routine.
The type of trial is decided in the code_pretrial component in the pretrial routine.
In this demo the targets are at fixed intervals. However, I usually add a jitter, e.g.
putTarget+=targetGap+randint(0,targetJitter)
If you wanted to adopt this principle in your code then you code have something like
conditions = []
minGap = 10
maxGap = 15
for i in range(len(wordlist)+len(targetlist):
if i == putTarget and len(targetList):
conditions.append(targetlist.pop())
putTarget+=randint(minGap,(maxGap+1))
else:
conditions.append(wordlist..pop())
Many thanks @wakecarter !
I did follow your solution but I got errors like could not convert the string to float
. Can’t understand why since I only used strings as strings. Anyway I saved the generated list as a csv file, then called this file with the trial loop and now everything works fine!
I write my entire solution below if anyone need it:
In my instruction routine (the first one) I inserted a code component
.
headers = [['stim', 'trigger_1']]
standardList = [['standard.wav', '1']]*1030
deviantList = [['deviant_1.wav', '3'], ['deviant_2.wav', '5'], ['deviant_3.wav', '7'], ['deviant_4.wav', '9']]*100
shuffle(deviantList)
stimList = []
minGap = 1
maxGap = 4
stim_num = 0
- In the Begin Routine tab:
# Make sure putDeviant will not be < 7
putDeviant = 6 + randint(minGap, (maxGap+1))
for i in range(len(standardList)+len(deviantList)):
# Make sure the 1st deviant appears after at least 7 standards
if stim_num < 7:
stimList .append(standardList.pop())
stim_num += 1
# Insert a deviant when the value of putDeeviant = i
elif i == putDeviant and len(deviantList):
stimList .append(deviantList.pop())
stim_num += 1
putDeviant = stim_num + randint(minGap, (maxGap+1))
# In other cases, insert a standard
else:
stimList .append(standardList.pop())
stim_num += 1
# Add headers to the stimuli list
all_stim = headers + stimList
# Write the list with the headeers into *.csv
filename_to_write = _thisDir + os.sep + 'MMN_stim_B1_random.csv'
np.savetxt(filename_to_write, all_stim, delimiter =";", fmt ='% s')
Then, I have my “normal routine” surrounded by a loop calling MMN_stim_B1_random.csv
to play the spoken stimuli.
Works perfectly 
Many thanks again!