I think this is the bit of code that is a problem. On inspection I seem to be asking the code to collect a lot of stuff on every single frame, which is unnecessary and I’m guessing (completely intuitively) could be the source of the problem? What do you guys think? In particular I seem to be resetting text on every single frame:
score_text = visual.TextStim(win=win, name='score_text', text= score_update ,font='Arial',pos=(0.6, 0.3), height=0.1, wrapWidth=None, ori=0, color='white', colorSpace='rgb', opacity=1,depth=-2.0)
Obviously this is a dumb thing to do, and I should update it. Is there any reason to think this might be the source of the problem? I had a chat with someone recently that said that memory usage in code was in itself a problem… I didn’t completely understand him. He was suggesting that I should do pretty much everything with functions, and that somehow this avoids memory usage - I guess that’s good advice? Looking at the code does anything jump out to you that could be the problem here. Given that the memory usage seems to be ramping up without any participant response, probably only the first layer of the loop will be of relevance (although if audio_stimulus.status == NOT_STARTED:
and if t = 0.0 and key_resp_2.status == NOT_STARTED:
will have run/started running).
I’m presuming that the various variable names here are intuitive, but I’m happy to describe them all/any of them, if required…:
while continueRoutine:
old_how_many_correct = how_many_correct
# get current time
t = trialClock.getTime()
score_text.setAutoDraw(False) # deletes the last score_text
# the below updates the text to be used as score_text:
score_update = (str(ggg) + ' melodies\nPart 1\n\nCompleted ' + str(how_many_goes) + ' / ' + str(total_conditions) + '\n' + 'Score = ' + str(how_many_correct) + '\n' + str(percent) + '%\n\nPrevious =\n' + str(is_it_correct) + '\n' + str(AP_correctAns) )
# the below updates the score_text:
score_text = visual.TextStim(win=win, name='score_text', text= score_update ,font='Arial',pos=(0.6, 0.3), height=0.1, wrapWidth=None, ori=0, color='white', colorSpace='rgb', opacity=1,depth=-2.0);
if audio_stimulus.status == NOT_STARTED:
# keep track of start time/frame for later
audio_stimulus.tStart = t
audio_stimulus.frameNStart = frameN # exact frame index
audio_stimulus.play() # start the sound (it finishes automatically)
# *key_resp_2* updates
if t >= 0.0 and key_resp_2.status == NOT_STARTED:
# keep track of start time/frame for later
key_resp_2.tStart = t
key_resp_2.frameNStart = frameN # exact frame index
key_resp_2.status = STARTED
# keyboard checking is just starting
win.callOnFlip(key_resp_2.clock.reset) # t=0 on next screen flip
event.clearEvents(eventType='keyboard')
# COLLECTING THE RESPONSES:
if key_resp_2.status == STARTED:
theseKeys = event.getKeys(keyList=key_strings) # will only collect keys from those specified in key_strings, all others are banned
# check for quit:
if "escape" in theseKeys:
endExpNow = True
########################################
if len(theseKeys) > 0: # at least one key was pressed
key_resp_2.keys = theseKeys[0] # just the last key pressed
key_resp_2.rt = key_resp_2.clock.getTime()
# was this 'correct'?...............:
# LOOP LAYER within 'if at least one key was pressed' loop:
if (key_resp_2.keys == str(corrAns)) or (key_resp_2.keys == corrAns):
key_resp_2.corr = 1 # store that the answer was correct
how_many_correct += 1 # tally that the answer was correct
how_many_goes +=1 # tally that 1 more go has taken place
AP_correctAns = songTitle # for the purpose of on screen text..
is_it_correct = 'Correct:' # for the purpose of on screen text..
percent = int((how_many_correct/how_many_goes) * 100) # for the purpose of on screen text..
audio_stimulus.stop() # stop playing the audio_stimulus
# WARNING! With the below code I initially wanted the correct_text to show, and the incorrect text to be set to finished, however, I couldn't get the correct_text to display, so this code is currently redundant I think
if t >= 0.0 and correct_text.status == NOT_STARTED:
correct_text.tStart = t
correct_text.frameNStart = frameN # exact frame index
correct_text.setAutoDraw(True)
incorrect_text.status = FINISHED
audio_feedback.status = FINISHED # the audio_feedback doesn't play if the response was correct
else:
key_resp_2.corr = 0 # store that the answer was incorrect
how_many_goes +=1 # tally that one more go has taken place
AP_correctAns = songTitle # for the purpose of on screen text..
is_it_correct = '' # for the purpose of on screen text..
percent = int((how_many_correct/how_many_goes) * 100) # for the purpose of on screen text..
audio_stimulus.stop() # stop playing the audio_stimulus
audio_feedback.tStart = t # start playing the audio_feedback
audio_feedback.frameNStart = frameN # exact frame index
audio_feedback.play()
# the below code starts the on screen text saying 'INCORRECT' and sets correct_text (currently redundant anyway) to FINISHED
if t >= 0.0 and incorrect_text.status == NOT_STARTED:
# keep track of start time/frame for later
incorrect_text.tStart = t
incorrect_text.frameNStart = frameN # exact frame index
incorrect_text.setAutoDraw(True)
correct_text.status = FINISHED
#################
# The next bit of code is probably redundant, as a response must be made in the experiment
if key_resp_2.keys in ['', [], None]: # No response was made
key_resp_2.keys=None
# was no response the correct answer?!
if str(corrAns).lower() == 'none':
key_resp_2.corr = 1 # correct non-response
else:
key_resp_2.corr = 0 # failed to respond (incorrect)
#store data for trials (TrialHandler)
trials.addData('key_resp_2.keys',key_resp_2.keys)
trials.addData('key_resp_2.corr', key_resp_2.corr)
if key_resp_2.keys != None: # we had a response
trials.addData('key_resp_2.rt', key_resp_2.rt)
##########################################################
#UPDATING THE ON SCREEN TEXT:
# *text_2* updates
if t >= 0.0 and text_2.status == NOT_STARTED:
# keep track of start time/frame for later
text_2.tStart = t
text_2.frameNStart = frameN # exact frame index
text_2.setAutoDraw(True)
# *score_text* updates
if t >= 0.0 and score_text.status == NOT_STARTED:
# keep track of start time/frame for later
score_text.tStart = t
score_text.frameNStart = frameN # exact frame index
score_text.setAutoDraw(True)
if audio_feedback.status == FINISHED and correct_text.status == FINISHED or incorrect_text.status == FINISHED:
continueRoutine = False
##########################################
# check if all components have finished
if not continueRoutine: # a component has requested a forced-end of Routine
break
continueRoutine = False # will revert to True if at least one component still running
for thisComponent in trialComponents:
if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
continueRoutine = True
break # at least one component has not yet finished
# check for quit (the Esc key)
if endExpNow or event.getKeys(keyList=["escape"]):
thisExp.saveAsWideText(filename+'.csv')
# added the save to excel file bit into the escape bit, to make sure it saves the data.
core.quit()
# refresh the screen
if continueRoutine: # don't flip if this routine is over or we'll get a blank screen
win.flip()
Thoughts? Thanks! 