私はPsychoPyのコーダセクションで実験を行っています。これは比較的簡単な作業ですが、テキストや画像の描画にはかなりの量が必要です。私は数日前(123件の試験からなる)全体の実験を実行してみました、と私は次のエラーを受け取った28日反復周り:PsychoPy textStimメモリリークの問題
WindowsError:例外:アクセス違反の書き込み0x00000004
私はこれに見て、ウィンドウに大量のテキストを描画するときに発生するpygletで発生するメモリリークの問題があるようです。私はコードが洗練されていて、実験で要求されたときにのみテキストコンポーネントを変更しました。私は、参照として以下に私の全体のコードをリストアップしています:
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()
誰でもメモリリークのエラーが発生しないように、より良いコードを改良する方法についての提案を持っている場合、私は思っていました。このエラーを解決できない場合は、PsychoPy Builderを使用して実験を複製するのが最善の解決策ですか?
最小限の再現可能な例を作成すると、問題を絞り込むだけでなく、コードを実際に読んでいる人の確率を上げるのに役立ちます。 –
つまり、実際に変更されたテキスト刺激のテキストプロパティのみを更新するように、既存のガイダンスに従っているかどうかは分かりません。また、できる限り、テキスト刺激を複数回作成しないでください。それらを一度作成し、必要に応じてプロパティを更新するだけです。 –
こんにちはマイケル、私は正しくそれをやっていると思ったので、テキストと画像の刺激を適切に更新するための確立された指針が何であるかを明確にすることができます。例えば、私のスクリプトの最上部付近では、imageという変数をイメージに設定し、その属性(つまり、位置、画像そのもの)を変更する必要がある場合は、スクリプトの残りの部分に画像を設定して変更します.image = etc、image.pos =など。私はこのメソッドがメモリに保存するのに良い方法だと思った。プロパティを更新する効率的な方法はありますか? – djl