Getting the filenames of clickable images as output?

Hi everyone,

I am trying to create a serial recall task using images. Participants are sequentially presented with 6 images one at a time. Then, a response screen comes up with all 6 images together, and participants are asked to click on the images in the order in which they appeared.

Presently, although I have successfully gotten the x,y coordinates of the mouse clicks, I would like the program to report the file names of the images that have been clicked on (e.g., they clicked on Image1.bmp, then Image2.bmp, then Image3.bmp, etc.), and then score whether these responses are correct. Does anyone know how to do this?

For reference, I’m running Psychopy Version 3 (standard standalone). I’m building the study on my laptop (Mac Sierra 10.12.6), but will be running it on Windows 7 in our lab.

Thanks!

Hi @Eris, I take it everything else is already set up. So you have an exposure routine that presents an image, and a loop that loops through the images serially at random. Following the completion of the loop, you will have the test routine, where 6 images are presented simultaneously onscreen at different locations, and the participant has to click them in the correct order. In the test routine, you will have 6 image components each presenting one of the images, and a mouse component?

If so, try the following. Make sure your mouse is set to never end the routine, to save mouse states on click, you have the image component names in clickable stimuli e.g., t1, t2 etc and ‘name’ as a parameter to store for clicked. Next, you will need a code component. In the code component, add the following to relevant tabs - note this example is only for 3 stim, you can fill in the rest. Here, t1, t2 etc are the names of the image components, and the mouse is called ‘mouse’

# Begin Routine
imagesClicked = []

# Every Frame
if mouse.isPressedIn(t1) and t1.name not in imagesClicked:
    imagesClicked.append(t1.name)
    mouse.clicked_name.append(t1.image)
if mouse.isPressedIn(t2)and t2.name not in imagesClicked:
    imagesClicked.append(t2.name)
    mouse.clicked_name.append(t2.image)
if mouse.isPressedIn(t3)and t3.name not in imagesClicked:
    imagesClicked.append(t3.name)
    mouse.clicked_name.append(t3.image) 

if (t1.name in imagesClicked 
    and t2.name in imagesClicked 
    and t3.name in imagesClicked):  # this will end the routine when all stim are clicked
    continueRoutine = False

Hi @dvbridges,

Thanks for your quick and helpful response. Yes, the experiment is set up precisely as you describe in the first paragraph.

I have followed your instructions in the second paragraph exactly, and have added your code to the end of my test routine. However, the input is still looking the same as before. I’m not entirely certain what the issue is. Should the code be placed in a specific place in the test routine code?

# Begin Routine of writing out file names
imagesClicked = []
# Every Frame
if mouse.isPressedIn(imageSICRTest1) and imageSICRTest1.name not in imagesClicked:
    imagesClicked.append(imageSICRTest1.name)
    mouse.clicked_name.append(imageSICRTest1.image)
if mouse.isPressedIn(imageSICRTest2)and imageSICRTest2.name not in imagesClicked:
    imagesClicked.append(imageSICRTest2.name)
mouse.clicked_name.append(imageSICRTest2.image)
if mouse.isPressedIn(imageSICRTest3)and imageSICRTest3.name not in imagesClicked:
    imagesClicked.append(imageSICRTest3.name)
    mouse.clicked_name.append(imageSICRTest3.image)
if mouse.isPressedIn(imageSICRTest4) and imageSICRTest4.name not in imagesClicked:
    imagesClicked.append(imageSICRTest4.name)
    mouse.clicked_name.append(imageSICRTest4.image)
if mouse.isPressedIn(imageSICRTest5)and imageSICRTest5.name not in imagesClicked:
    imagesClicked.append(imageSICRTest5.name)
    mouse.clicked_name.append(imageSICRTest5.image)
if mouse.isPressedIn(imageSICRTest6)and imageSICRTest6.name not in imagesClicked:
    imagesClicked.append(imageSICRTest6.name)
    mouse.clicked_name.append(imageSICRTest6.image) 
if (imageSICRTest1.name in imagesClicked 
    and imageSICRTest2.name in imagesClicked 
    and imageSICRTest3.name in imagesClicked 
    and imageSICRTest4.name in imagesClicked 
    and imageSICRTest5.name in imagesClicked 
    and imageSICRTest6.name in imagesClicked):  # this will end the routine when all stim are clicked
    continueRoutine = False

Great. Yes, the code should be placed in the relevant tabs that are described using the comments:

e.g.,

# Begin Routine - add only the next line to Begin Routine
imagesClicked = []

# Each Frame - add all following lines to Each Frame tab
if mouse.isPressedIn(imageSICRTest1) and imageSICRTest1.name not in ...etc

That worked! Thank you!

If I may ask a follow-up question, is it possible to get the output to record each response in different columns rather than within the same cell in the output CSV?

Yes no problem. In your end routine tab of the code component for the test stage:

for idx, images in enumerate(mouse.clicked_name):
    thisExp.addData("clickN{}".format(idx), images)

That worked perfectly. Thank you again for all your help!

@dvbridges Is there a way to make it such that the selected images are scored as correct/incorrect? Based on the code you provided yesterday, I’ve tried adding the following code to my “End Routine” tab, to get the scores outputted to separate columns, but it hasn’t worked. The program can’t find the clickN# variable:

#separate image responses into separate columns in output csv
for idx, images in enumerate(mouse.clicked_name):
thisExp.addData(“clickN{}”.format(idx), images)

correct_answers = [CorrectAns0, CorrectAns1, CorrectAns2, CorrectAns3, CorrectAns4, CorrectAns5]
user_selections = [clickN0, clickN1, clickN2, clickN3, clickN4, clickN5]

match = [x == y for (x, y) in zip(correct_answers, user_selections)]

for index, entry in enumerate(match):
trialsStudy.addData(‘isCorrectS’+str(index), int(entry))

Hi @Eris, yes those variables (clickN etc) only exist as variables in your datafile. However, you have the list called mouse.clicked_name, which has the order in which images were clicked. The following works given that your correct_answers variable contains filenames of your images:

match = [x == y for (x, y) in zip(correct_answers, mouse.clicked_name)]

for index, entry in enumerate(match):
    trialsStudy.addData('isCorrectS'+str(index), int(entry))
trialsStudy.addData('completeMatch', np.all(match))  # Adds column with bool for complete match