From 566854860c847ca42fd141612b137e51c73ed103 Mon Sep 17 00:00:00 2001 From: "Jeremy R. Gray" Date: Sun, 2 Mar 2014 17:24:25 -0500 Subject: [PATCH] ENH: allow saving of data without needing a loop; see #71 --- psychopy/app/builder/components/keyboard.py | 10 ++++++-- psychopy/app/builder/components/mouse.py | 26 ++++++++++++++------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/psychopy/app/builder/components/keyboard.py b/psychopy/app/builder/components/keyboard.py index 75ef8f28bc4..df154736407 100644 --- a/psychopy/app/builder/components/keyboard.py +++ b/psychopy/app/builder/components/keyboard.py @@ -6,6 +6,7 @@ from os import path from psychopy.app.builder.experiment import CodeGenerationException, _valid_var_re +from psychopy.app.builder.experiment import TrialHandler thisFolder = path.abspath(path.dirname(__file__))#the absolute path to the folder containing this path iconFile = path.join(thisFolder,'keyboard.png') @@ -177,10 +178,13 @@ def writeRoutineEndCode(self,buff): store=self.params['store'].val if len(self.exp.flow._loopList): currLoop=self.exp.flow._loopList[-1]#last (outer-most) loop - else: currLoop=None + else: + # dummy TrialHandler, same name as the ExperimentHandler that will be created in the exp script: + currLoop = TrialHandler(self.exp, name='thisExp') + currLoop.type = 'ExperimentHandler' # displayed in a code comment #write the actual code - if (store!='nothing') and currLoop:#need a loop to do the storing of data! + if store != 'nothing': # there's always a loop: user defined or thisExp (implicitly) buff.writeIndented("# check responses\n" %self.params) buff.writeIndented("if %(name)s.keys in ['', [], None]: # No response was made\n"%self.params) buff.writeIndented(" %(name)s.keys=None\n" %(self.params)) @@ -205,3 +209,5 @@ def writeRoutineEndCode(self,buff): buff.writeIndented("if %(name)s.keys != None: # we had a response\n" %(self.params)) buff.writeIndented(" %s.addData('%s.rt', %s.rt)\n" \ %(currLoop.params['name'], name, name)) + if currLoop.params['name'].val == 'thisExp': + buff.writeIndented("thisExp.nextEntry()\n") diff --git a/psychopy/app/builder/components/mouse.py b/psychopy/app/builder/components/mouse.py index f0b23f4def5..8e87fb346c9 100644 --- a/psychopy/app/builder/components/mouse.py +++ b/psychopy/app/builder/components/mouse.py @@ -4,7 +4,7 @@ from _base import * from os import path -from psychopy.app.builder.experiment import Param +from psychopy.app.builder.experiment import Param, TrialHandler thisFolder = path.abspath(path.dirname(__file__))#the absolute path to the folder containing this path iconFile = path.join(thisFolder,'mouse.png') @@ -136,14 +136,20 @@ def writeRoutineEndCode(self,buff): name = self.params['name'] store = self.params['saveMouseState'].val#do this because the param itself is not a string! forceEnd = self.params['forceEndRoutineOnPress'].val - #check if we're in a loop (so saving is possible) if len(self.exp.flow._loopList): currLoop=self.exp.flow._loopList[-1]#last (outer-most) loop - else: currLoop=None - if store!='nothing' and currLoop and currLoop.type=='StairHandler': - buff.writeIndented("# NB PsychoPy doesn't handle a 'correct answer' for mouse events so doesn't know how to handle mouse with StairHandler") - if store == 'final' and currLoop!=None: - buff.writeIndented("# get info about the %(name)s\n" %(self.params)) + else: + # dummy TrialHandler, same name as the ExperimentHandler that will be created in the exp script: + currLoop = TrialHandler(self.exp, name='thisExp') + currLoop.type = 'ExperimentHandler' # displayed in a code comment + + if store != 'nothing': + if currLoop.type=='StairHandler': + buff.writeIndented("# NB PsychoPy doesn't handle a 'correct answer' for mouse events so doesn't know how to handle mouse with StairHandler") + else: + buff.writeIndented("# store data for %s (%s)\n" %(currLoop.params['name'], currLoop.type)) + if store == 'final': + #buff.writeIndented("# get info about the %(name)s\n" %(self.params)) buff.writeIndented("x, y = %(name)s.getPos()\n" %(self.params)) buff.writeIndented("buttons = %(name)s.getPressed()\n" %(self.params)) if currLoop.type!='StairHandler': @@ -152,11 +158,13 @@ def writeRoutineEndCode(self,buff): buff.writeIndented("%s.addData('%s.leftButton', buttons[0])\n" %(currLoop.params['name'], name)) buff.writeIndented("%s.addData('%s.midButton', buttons[1])\n" %(currLoop.params['name'], name)) buff.writeIndented("%s.addData('%s.rightButton', buttons[2])\n" %(currLoop.params['name'], name)) - elif store != 'never' and currLoop!=None: - buff.writeIndented("# save %(name)s data\n" %(self.params)) + elif store != 'never': + #buff.writeIndented("# save %(name)s data\n" %(self.params)) for property in ['x','y','leftButton','midButton','rightButton','time']: if store=='every frame' or not forceEnd: buff.writeIndented("%s.addData('%s.%s', %s.%s)\n" %(currLoop.params['name'], name,property,name,property)) else: #we only had one click so don't return a list buff.writeIndented("%s.addData('%s.%s', %s.%s[0])\n" %(currLoop.params['name'], name,property,name,property)) + if store != 'nothing' and currLoop.params['name'].val == 'thisExp': + buff.writeIndented("thisExp.nextEntry()\n")