I've been developing an experiment in the coder section of PsychoPy. It's a relatively simple task but requires a fair amount to text and image drawing. I tried running the entire experiment (consists of 123 trials) a few days ago, and around the 28th iteration I received the following error:
WindowsError: exception: access violation writing 0x00000004
I looked into this, and it appears that there is a memory leak issues caused in pyglet that occurs when drawing a large amount of text stim to the window. I refined my code to only change the text components when the experiment demands it. I'm listing my entire code below as a reference:
from __future__ import division
from psychopy import locale_setup, visual, core, event, data, gui
import numpy as np
import pandas as pd
import sys, os, csv, time, random
from win32api import GetSystemMetrics
#Directory:
cwd = os.path.dirname(os.path.abspath(__file__))
#GUI:
expName = "CMNT"
expInfo = {"participant": "", "session": "001", "condition": "F1"} #Condition Files: F1, F2, M1, or M2
condition = expInfo["condition"]
condition = expInfo["condition"]
dlg = gui.DlgFromDict(dictionary = expInfo, title = expName, order = ["participant","session","condition"])
if dlg.OK == False:
core.quit()
#Window:
win = visual.Window(size = (GetSystemMetrics(0), GetSystemMetrics(1)), fullscr = True, pos = (0,0), units = "norm", color = "Gray")
#Turn off Mouse
event.Mouse(visible = False)
#Timers:
timer = core.Clock()
breakTimer = core.Clock()
#Load Condition File:
stim_df = pd.read_csv("exp_stimuli.csv", nrows = 124)
run_length = 123
#Output Directory:
fileLocation = cwd + "\%s_data\%s" %(expName, expInfo["participant"])
if not os.path.exists(fileLocation):
os.makedirs(fileLocation)
os.chdir(fileLocation)
if os.path.isfile("logFile.csv"):
os.remove("logFile.csv")
#List and Panda File Header
run_param_list = []
header = ["Block","MentalState", "Condition", "Speaker","Prompt", "RespButton", "CorrAnswer","RT(sec)", "ACC"]
#Define text and image stimuli
text = visual.TextStim(win = win, text = '', height = 0.1, pos = (0,0), color="White")
image = visual.ImageStim(win = win, pos = (0,0), size = (0.1,0.1), image = cwd + "\\" + "gray.png")
#Run Instruction Page:
text.text = '\t\tREMEMBER:\n\t\tAnswer each question,\n\t\t"Which should I pick?"\n\t\tusing the LEFT and RIGHT\n\t\tarrow key.'
text.height = 0.1
text.draw()
win.flip()
while True:
theseKeys = event.getKeys()
if "escape" in theseKeys:
core.quit()
if len(theseKeys):
break
#Begin Trials:
for i in xrange(run_length):
if stim_df["MentalState"][i] == "0":
breakTimer.reset()
while breakTimer.getTime() < 15.0:
text.text = "+"
text.height = 0.25
text.pos = (0,0)
text.draw()
win.flip()
else:
#win.flip()
timer.reset()
exit_press = []
event_press = []
speaker = visual.TextStim(win, text = stim_df["speaker"][i], height = 0.1, pos = (0,0.6))
speaker.setAutoDraw(True)
#0.5 seconds
while timer.getTime() < 0.5:
win.flip()
#3.0 seconds
if stim_df["speaker"][i] == "Computer":
text.text = stim_df["prompt"][i]
text.pos = (-0.1,0)
text.height = 0.08
text_box_length = text.boundingBox[0]/GetSystemMetrics(0)*2
image.image = cwd + "\\" + "gray.png"
image.pos = (-0.1,0)
image.size = (text_box_length, 0.35)
image.draw()
text.draw()
else:
text.text = stim_df["prompt"][i]
text.pos = (-0.1,0)
text.height = 0.08
text_box_length = text.boundingBox[0]/GetSystemMetrics(0)*2
image.image = cwd + "\\" + "blue.png"
image.pos = (-0.1,0)
image.size = (text_box_length, 0.35)
image.draw()
text.draw()
win.flip()
while timer.getTime() < 3.5:
exit_press += event.getKeys()
if "escape" in exit_press:
core.quit()
onset_Time = timer.getTime()
speaker.setAutoDraw(False)
#3.5 seconds
text.text = stim_df["question"][i]
text.pos = (0,0.6)
text.height = 0.1
text.draw()
text.text = stim_df["answerA"][i]
text.pos = (-0.3, -0.5)
text.draw()
text.text = stim_df["answerB"][i]
text.pos = (0.3, -0.5)
text.height = 0.1
text.draw()
win.flip()
length = 0
while timer.getTime() < 7.0:
event_press += event.getKeys(keyList = ["left","right"])
if len(event_press) > length:
RT = timer.getTime() - onset_Time
length = len(event_press)
elif len(event_press) == 0:
RT = "N/A"
exit_press += event.getKeys()
if "escape" in exit_press:
core.quit()
#Jitter 1 time
text.text = "+"
text.pos = (0,0)
text.height = 0.25
text.draw()
win.flip()
while timer.getTime() < 7.0 + (stim_df["jitter1"][i]/1000):
exit_press += event.getKeys()
if "escape" in exit_press:
core.quit()
#Check Conditional Input
try:
response = event_press[-1]
except:
response = None
if response == "left":
reply = stim_df["answerA"][i]
if reply == stim_df["corrAnswer"][i]:
acc = 1
else:
acc = 0
elif response == "right":
reply = stim_df["answerB"][i]
if reply == stim_df["corrAnswer"][i]:
acc = 1
else:
acc = 0
elif response == None:
response = "N/A"
reply = stim_df["corrAnswer"][i]
acc = 0
text.text = reply
text.height = 0.08
text.pos = (0.1,0.3)
#2 seconds
if stim_df["speaker"][i] == "Computer":
text.text = reply
text.height = 0.08
text.pos = (0.1,0.3)
speaker.draw()
image.image = cwd + "\\" + "gray.png"
image.size = (text.boundingBox[0]/GetSystemMetrics(0)*2 + 0.2, text.boundingBox[1]/GetSystemMetrics(1)*2 + 0.1)
image.pos = (0.1, 0.3)
image.draw()
text.draw()
text.pos = (-0.1,-0.1)
text.text = reply + u" \u2713"
text_box_length = text.boundingBox[0]/GetSystemMetrics(0)*2 + 0.1
image.image = cwd + "\\" + "gray.png"
image.size = (text.boundingBox[0]/GetSystemMetrics(0)*2 + 0.1, text.boundingBox[1]/GetSystemMetrics(1)*2 + 0.1)
image.pos = (-0.1,-0.1)
image.draw()
text.draw()
else:
text.text = reply
text.height = 0.08
text.pos = (0.1,0.3)
speaker.draw()
image.image = cwd + "\\" + "green.png"
image.size = (text.boundingBox[0]/GetSystemMetrics(0)*2 + 0.1, text.boundingBox[1]/GetSystemMetrics(1)*2 + 0.1)
image.pos = (0.1,0.3)
image.draw()
text.draw()
text.text = reply + " :)"
text.pos = (-0.1,-0.1)
image.image = cwd + "\\" + "blue.png"
image.size = (text.boundingBox[0]/GetSystemMetrics(0)*2 + 0.1, text.boundingBox[1]/GetSystemMetrics(1)*2 + 0.1)
image.pos = (-0.1, -0.1)
image.draw()
text.draw()
win.flip()
while timer.getTime() < 9.0 + (stim_df["jitter1"][i]/1000):
exit_press += event.getKeys()
if "escape" in exit_press:
core.quit()
#Jitter 2 time
text.text = "+"
text.height = 0.25
text.pos = (0,0)
text.draw()
win.flip()
while timer.getTime() < 11.0 + (stim_df["jitter1"][i]/1000) + (stim_df["jitter2"][i]/1000):
exit_press += event.getKeys()
if "escape" in exit_press:
core.quit()
#Panda Output File
run_param_list.append([stim_df["block"][i], stim_df["MentalState"][i], condition, stim_df["speaker"][i], stim_df["prompt"][i], response, stim_df["corrAnswer"][i], RT, acc])
fid = pd.DataFrame(run_param_list, columns = header)
fid.to_csv("logFile.csv", header = True)
#Close up Shop:
win.close()
core.quit()
I was wondering if anyone has a suggestion as to how to refine the code better so that the memory leak error won't occur. If this error can't be fixed, would the best solution be to replicate the experiment through PsychoPy Builder?