Example #1
0
    def writeLoopStartCode(self, buff):
        """Write the code to create and run a sequence of trials
        """
        # first create the handler init values
        inits = getInitVals(self.params)
        # import conditions from file?
        if self.params['conditionsFile'].val in ['None', None, 'none', '']:
            condsStr = "[None]"
        elif self.params['Selected rows'].val in ['None', None, 'none', '']:
            # just a conditions file with no sub-selection
            _con = "data.importConditions(%s)"
            condsStr = _con % self.params['conditionsFile']
        else:
            # a subset of a conditions file
            condsStr = ("data.importConditions(%(conditionsFile)s, selection="
                        "%(Selected rows)s)") % self.params
        # also a 'thisName' for use in "for thisTrial in trials:"
        makeLoopIndex = self.exp.namespace.makeLoopIndex
        self.thisName = makeLoopIndex(self.params['name'].val)
        # write the code
        code = (
            "\n# set up handler to look after randomisation of conditions etc\n"
            "%(name)s = data.TrialHandler(nReps=%(nReps)s, method=%(loopType)s, \n"
            "    extraInfo=expInfo, originPath=-1,\n")
        buff.writeIndentedLines(code % inits)
        # the next line needs to be kept separate to preserve potential string formatting
        # by the user in condStr (i.e. it shouldn't be a formatted string itself
        code = "    trialList=" + condsStr + ",\n"  # conditions go here
        buff.writeIndented(code)
        code = "    seed=%(random seed)s, name='%(name)s')\n"
        buff.writeIndentedLines(code % inits)

        code = (
            "thisExp.addLoop(%(name)s)  # add the loop to the experiment\n" +
            self.thisName + " = %(name)s.trialList[0]  " +
            "# so we can initialise stimuli with some values\n")
        buff.writeIndentedLines(code % self.params)
        # unclutter the namespace
        if not self.exp.prefsBuilder['unclutteredNamespace']:
            code = (
                "# abbreviate parameter names if possible (e.g. rgb = %(name)s.rgb)\n"
                "if %(name)s != None:\n"
                "    for paramName in %(name)s:\n"
                "        exec('{} = %(name)s[paramName]'.format(paramName))\n")
            buff.writeIndentedLines(code % {'name': self.thisName})

        # then run the trials loop
        code = "\nfor %s in %s:\n"
        buff.writeIndentedLines(code % (self.thisName, self.params['name']))
        # fetch parameter info from conditions
        buff.setIndentLevel(1, relative=True)
        buff.writeIndented("currentLoop = %s\n" % self.params['name'])
        # unclutter the namespace
        if not self.exp.prefsBuilder['unclutteredNamespace']:
            code = (
                "# abbreviate parameter names if possible (e.g. rgb = %(name)s.rgb)\n"
                "if %(name)s != None:\n"
                "    for paramName in %(name)s:\n"
                "        exec('{} = %(name)s[paramName]'.format(paramName))\n")
            buff.writeIndentedLines(code % {'name': self.thisName})
Example #2
0
 def test_params_used(self):
     # Make minimal experiment just for this test
     rt, exp = _make_minimal_experiment(self)
     # Try with PsychoPy and PsychoJS
     for target in ("PsychoPy", "PsychoJS"):
         ## Skip PsychoJS until can write script without saving
         if target == "PsychoJS":
             continue
         # Skip unimplemented targets
         if target not in rt.targets:
             continue
         # Compile script
         script = exp.writeScript(target=target)
         # Check that the string value of each param is present in the script
         experiment.utils.scriptTarget = target
         # Iterate through every param
         for routine in exp.flow:
             for name, param in experiment.getInitVals(
                     routine.params, target).items():
                 # Conditions to skip...
                 if not param.direct:
                     # Marked as not direct
                     continue
                 if any(name in depend['param']
                        for depend in routine.depends):
                     # Dependent on another param
                     continue
                 # Check that param is used
                 assert str(param) in script, (
                     f"Value {param} of <psychopy.experiment.params.Param: val={param.val}, valType={param.valType}> "
                     f"in {type(rt).__name__} not found in {target} script."
                 )
Example #3
0
    def writeLoopStartCode(self, buff):
        """Write the code to create and run a sequence of trials
        """
        # first create the handler init values
        inits = getInitVals(self.params)
        # import conditions from file?
        if self.params['conditionsFile'].val in ['None', None, 'none', '']:
            condsStr = "[None]"
        elif self.params['Selected rows'].val in ['None', None, 'none', '']:
            # just a conditions file with no sub-selection
            _con = "data.importConditions(%s)"
            condsStr = _con % self.params['conditionsFile']
        else:
            # a subset of a conditions file
            condsStr = ("data.importConditions(%(conditionsFile)s, selection="
                        "%(Selected rows)s)") % self.params
        # also a 'thisName' for use in "for thisTrial in trials:"
        makeLoopIndex = self.exp.namespace.makeLoopIndex
        self.thisName = makeLoopIndex(self.params['name'].val)
        # write the code
        code = ("\n# set up handler to look after randomisation of conditions etc\n"
                "%(name)s = data.TrialHandler(nReps=%(nReps)s, method=%(loopType)s, \n"
                "    extraInfo=expInfo, originPath=-1,\n")
        buff.writeIndentedLines(code % inits)
        # the next line needs to be kept separate to preserve potential string formatting
        # by the user in condStr (i.e. it shouldn't be a formatted string itself
        code = "    trialList=" + condsStr + ",\n"  # conditions go here
        buff.writeIndented(code)
        code = "    seed=%(random seed)s, name='%(name)s')\n"
        buff.writeIndentedLines(code % inits)

        code = ("thisExp.addLoop(%(name)s)  # add the loop to the experiment\n" +
                self.thisName + " = %(name)s.trialList[0]  " +
                "# so we can initialise stimuli with some values\n")
        buff.writeIndentedLines(code % self.params)
        # unclutter the namespace
        if not self.exp.prefsBuilder['unclutteredNamespace']:
            code = ("# abbreviate parameter names if possible (e.g. rgb = %(name)s.rgb)\n"
                    "if %(name)s != None:\n"
                    "    for paramName in %(name)s:\n"
                    "        exec('{} = %(name)s[paramName]'.format(paramName))\n")
            buff.writeIndentedLines(code % {'name': self.thisName})

        # then run the trials loop
        code = "\nfor %s in %s:\n"
        buff.writeIndentedLines(code % (self.thisName, self.params['name']))
        # fetch parameter info from conditions
        buff.setIndentLevel(1, relative=True)
        buff.writeIndented("currentLoop = %s\n" % self.params['name'])
        # unclutter the namespace
        if not self.exp.prefsBuilder['unclutteredNamespace']:
            code = ("# abbreviate parameter names if possible (e.g. rgb = %(name)s.rgb)\n"
                    "if %(name)s != None:\n"
                    "    for paramName in %(name)s:\n"
                    "        exec('{} = %(name)s[paramName]'.format(paramName))\n")
            buff.writeIndentedLines(code % {'name': self.thisName})
Example #4
0
 def test_params_used(self):
     # Change eyetracking settings
     self.expPy.settings.params['eyetracker'].val = "MouseGaze"
     # Test both python and JS
     for target, exp in {
             "PsychoPy": self.expPy,
             "PsychoJS": self.expJS
     }.items():
         # todo: add JS exceptions
         if target == "PsychoJS":
             continue
         # Iterate through each component
         for compName, component in self.allComp.items():
             # Skip if not valid for this (or any) target
             if target not in component.targets:
                 continue
             if compName == "SettingsComponent":
                 continue
             if compName in ['RatingScaleComponent', 'PatchComponent']:
                 continue
             # Make a routine for this component
             rt = exp.addRoutine(compName + "Routine")
             comp = component(parentName=compName + "Routine", exp=exp)
             rt.append(comp)
             exp.flow.addRoutine(rt, 0)
             # Compile script
             script = exp.writeScript(target=target)
             # Check that the string value of each param is present in the script
             experiment.utils.scriptTarget = target
             # Iterate through every param
             for paramName, param in experiment.getInitVals(
                     comp.params, target).items():
                 # Conditions to skip...
                 if not param.direct:
                     # Marked as not direct
                     continue
                 if any(paramName in depend['param']
                        for depend in comp.depends):
                     # Dependent on another param
                     continue
                 if param.val in [
                         "from exp settings",  # units and color space, aliased
                         'default',  # most of the time will be aliased
                 ]:
                     continue
                 # Check that param is used
                 assert str(
                     param
                 ) in script, f"Could not find {target}.{type(comp).__name__}.{paramName}: <psychopy.experiment.params.Param: val={param.val}, valType={param.valType}> in script:\n\n{script}"
             # Remove routine
             exp.flow.removeComponent(rt)
Example #5
0
 def test_params_used(self):
     # Make minimal experiment just for this test
     comp, rt, exp = _make_minimal_experiment(self)
     # Skip if component shouldn't use all of its params
     if type(comp).__name__ in ["SettingsComponent", "CodeComponent"]:
         pytest.skip()
     # Skip if component is deprecated
     if type(comp).__name__ in ['RatingScaleComponent', 'PatchComponent']:
         pytest.skip()
     # Try with PsychoPy and PsychoJS
     for target in ("PsychoPy", "PsychoJS"):
         ## Skip PsychoJS until can write script without saving
         if target == "PsychoJS":
             continue
         # Skip if not valid for this target
         if target not in comp.targets:
             continue
         # Compile script
         script = exp.writeScript(target=target)
         # Check that the string value of each param is present in the script
         experiment.utils.scriptTarget = target
         # Iterate through every param
         for paramName, param in experiment.getInitVals(
                 comp.params, target).items():
             # Conditions to skip...
             if not param.direct:
                 # Marked as not direct
                 continue
             if any(paramName in depend['param']
                    for depend in comp.depends):
                 # Dependent on another param
                 continue
             if param.val in [
                     "from exp settings",  # units and color space, aliased
                     'default',  # most of the time will be aliased
             ]:
                 continue
             # Check that param is used
             assert str(param) in script, (
                 f"Value {param} of <psychopy.experiment.params.Param: val={param.val}, valType={param.valType}> "
                 f"in {type(comp).__name__} not found in {target} script.")
Example #6
0
 def test_params_used(self):
     # Change eyetracking settings
     self.expPy.settings.params['eyetracker'].val = "MouseGaze"
     # Test both python and JS
     for target, exp in {
             "PsychoPy": self.expPy,
             "PsychoJS": self.expJS
     }.items():
         for rtName, routine in self.routines.items():
             # Skip if not valid for this (or any) target
             if target not in routine.targets:
                 continue
             # Make routine
             rt = routine(exp)
             rt = exp.addStandaloneRoutine(rtName, rt)
             exp.flow.addRoutine(rt, 0)
             # Compile script
             script = exp.writeScript(target=target)
             # Check that the string value of each param is present in the script
             experiment.utils.scriptTarget = target
             # Iterate through every param
             for routine in exp.flow:
                 for name, param in experiment.getInitVals(
                         routine.params, target).items():
                     # Conditions to skip...
                     if not param.direct:
                         # Marked as not direct
                         continue
                     if any(name in depend['param']
                            for depend in routine.depends):
                         # Dependent on another param
                         continue
                     # Check that param is used
                     assert str(
                         param
                     ) in script, f"{target}.{type(routine).__name__}.{name}: <psychopy.experiment.params.Param: val={param.val}, valType={param.valType}>"