Exemplo n.º 1
0
    def writeInitCodeJS(self, buff):
        inits = getInitVals(self.params)
        for param in inits:
            if inits[param].val in ['', None, 'None', 'none']:
                inits[param].val = 'undefined'

        # Check for unsupported units
        if inits['units'].val == 'from exp settings':
            inits['units'] = copy.copy(self.exp.settings.params['Units'])
        if inits['units'].val in ['cm', 'deg', 'degFlatPos', 'degFlat']:
            msg = ("'{units}' units for your '{name}' Slider are not currently supported for PsychoJS: "
                  "switching units to 'height'. Note, this will affect the size and positioning of '{name}'.")
            logging.warning(msg.format(units=inits['units'].val, name=inits['name'].val))
            inits['units'].val = "height"

        boolConverter = {False: 'false', True: 'true'}
        sliderStyles = {'slider': 'SLIDER',
                        'scrollbar': 'SLIDER',
                        '()': 'RATING',
                        'rating': 'RATING',
                        'radio': 'RADIO',
                        'labels45': 'LABELS_45',
                        'whiteOnBlack': 'WHITE_ON_BLACK',
                        'triangleMarker': 'TRIANGLE_MARKER'}

        # If no style given, set default 'rating' as list
        if len(inits['styles'].val) == 0:
            inits['styles'].val = 'rating'

        # reformat styles for JS
        # concatenate styles and tweaks
        tweaksList = utils.listFromString(self.params['styleTweaks'].val)
        if type(inits['styles'].val) == list:  # from an experiment <2021.1
            stylesList = inits['styles'].val + tweaksList
        else:
            stylesList = [inits['styles'].val] + tweaksList
        stylesListJS = [sliderStyles[this] for this in stylesList]
        # if not isinstance(inits['styleTweaks'].val, (tuple, list)):
        #     inits['styleTweaks'].val = [inits['styleTweaks'].val]
        # inits['styleTweaks'].val = ', '.join(["visual.Slider.StyleTweaks.{}".format(adj)
        #                                       for adj in inits['styleTweaks'].val])

        # convert that to string and JS-ify
        inits['styles'].val = py2js.expression2js(str(stylesListJS))
        inits['styles'].valType = 'code'

        inits['depth'] = -self.getPosInRoutine()

        # build up an initialization string for Slider():
        initStr = ("{name} = new visual.Slider({{\n"
                   "  win: psychoJS.window, name: '{name}',\n"
                   "  size: {size}, pos: {pos}, units: {units},\n"
                   "  labels: {labels}, ticks: {ticks},\n"
                   "  granularity: {granularity}, style: {styles},\n"
                   "  color: new util.Color({color}), \n"
                   "  fontFamily: {font}, bold: true, italic: false, depth: {depth}, \n"
                   ).format(**inits)
        initStr += ("  flip: {flip},\n"
                    "}});\n\n").format(flip=boolConverter[inits['flip'].val])
        buff.writeIndentedLines(initStr)
Exemplo n.º 2
0
    def writeInitCodeJS(self, buff):
        inits = getInitVals(self.params)
        for param in inits:
            if inits[param].val in ['', None, 'None', 'none']:
                inits[param].val = 'undefined'

        # Check for unsupported units
        if inits['units'].val == 'from exp settings':
            inits['units'] = copy.copy(self.exp.settings.params['Units'])
        if inits['units'].val in ['cm', 'deg', 'degFlatPos', 'degFlat']:
            msg = (
                "'{units}' units for your '{name}' Slider are not currently supported for PsychoJS: "
                "switching units to 'height'. Note, this will affect the size and positioning of '{name}'."
            )
            logging.warning(
                msg.format(units=inits['units'].val, name=inits['name'].val))
            inits['units'].val = "height"

        boolConverter = {False: 'false', True: 'true'}
        sliderStyles = {
            'slider': 'SLIDER',
            '()': 'RATING',
            'rating': 'RATING',
            'radio': 'RADIO',
            'labels45': 'LABELS_45',
            'whiteOnBlack': 'WHITE_ON_BLACK',
            'triangleMarker': 'TRIANGLE_MARKER'
        }

        # If no style given, set default 'rating' as list
        if len(inits['styles'].val) == 0:
            inits['styles'].val = ['rating']

        # reformat styles for JS
        inits['styles'].val = ', '.join([
            "visual.Slider.Style.{}".format(sliderStyles[style])
            for style in inits['styles'].val
        ])
        # add comma so is treated as tuple in py2js and converted to list, as required
        inits['styles'].val += ','
        inits['styles'].val = py2js.expression2js(inits['styles'].val)

        inits['depth'] = -self.getPosInRoutine()

        # build up an initialization string for Slider():
        initStr = (
            "{name} = new visual.Slider({{\n"
            "  win: psychoJS.window, name: '{name}',\n"
            "  size: {size}, pos: {pos}, units: {units},\n"
            "  labels: {labels}, ticks: {ticks},\n"
            "  granularity: {granularity}, style: {styles},\n"
            "  color: new util.Color({color}), \n"
            "  fontFamily: {font}, bold: true, italic: false, depth: {depth}, \n"
        ).format(**inits)
        initStr += ("  flip: {flip},\n"
                    "}});\n\n").format(flip=boolConverter[inits['flip'].val])
        buff.writeIndentedLines(initStr)
Exemplo n.º 3
0
    def test_Py2js_Expression2js(self):
        """Test that converts a short expression (e.g. a Component Parameter) Python to JS"""
        input = [
            'sin(t)', 'cos(t)', 'tan(t)', 'pi', 'rand', 'random', 't*5',
            '(3, 4)', '(5*-2)', '(1,(2,3))', '2*(2, 3)', '[1, (2*2)]',
            '(.7, .7)', '(-.7, .7)', '[-.7, -.7]', '[-.7, (-.7 * 7)]'
        ]

        output = [
            'Math.sin(t)', 'Math.cos(t)', 'Math.tan(t)', 'Math.PI',
            'Math.random', 'Math.random', '(t * 5)', '[3, 4]', '(5 * (- 2))',
            '[1, [2, 3]]', '(2 * [2, 3])', '[1, (2 * 2)]', '[0.7, 0.7]',
            '[(- 0.7), 0.7]', '[(- 0.7), (- 0.7)]', '[(- 0.7), ((- 0.7) * 7)]'
        ]

        for idx, expr in enumerate(input):
            # check whether direct match or at least a match when spaces removed
            assert (py2js.expression2js(expr) == output[idx]
                    or py2js.expression2js(expr).replace(
                        " ", "") == output[idx].replace(" ", ""))
Exemplo n.º 4
0
    def test_Py2js_Expression2js(self):
        """Test that converts a short expression (e.g. a Component Parameter) Python to JS"""
        input = ['sin(t)',
                 'cos(t)',
                 'tan(t)',
                 'pi',
                 'rand',
                 'random',
                 't*5',
                 '(3, 4)',
                 '(5*-2)',
                 '(1,(2,3))',
                 '2*(2, 3)',
                 '[1, (2*2)]',
                 '(.7, .7)',
                 '(-.7, .7)',
                 '[-.7, -.7]',
                 '[-.7, (-.7 * 7)]']

        output = ['Math.sin(t)',
                  'Math.cos(t)',
                  'Math.tan(t)',
                  'Math.PI',
                  'Math.random',
                  'Math.random',
                  '(t * 5)',
                  '[3, 4]',
                  '(5 * (- 2))',
                  '[1, [2, 3]]',
                  '(2 * [2, 3])',
                  '[1, (2 * 2)]',
                  '[0.7, 0.7]',
                  '[(- 0.7), 0.7]',
                  '[(- 0.7), (- 0.7)]',
                  '[(- 0.7), ((- 0.7) * 7)]']

        for idx, expr in enumerate(input):
            # check whether direct match or at least a match when spaces removed
            assert (py2js.expression2js(expr) == output[idx] or
            py2js.expression2js(expr).replace(" ", "") == output[idx].replace(" ", ""))
Exemplo n.º 5
0
    def writeInitCodeJS(self, buff):
        inits = getInitVals(self.params)
        for param in inits:
            if inits[param].val in ['', None, 'None', 'none']:
                inits[param].val = 'undefined'
        boolConverter = {False: 'false', True: 'true'}
        sliderStyles = {
            'slider': 'SLIDER',
            '()': 'RATING',
            'rating': 'RATING',
            'radio': 'RADIO',
            'labels45': 'LABELS_45',
            'whiteOnBlack': 'WHITE_ON_BLACK',
            'triangleMarker': 'TRIANGLE_MARKER'
        }

        # If no style given, set default 'rating' as list
        if len(inits['styles'].val) == 0:
            inits['styles'].val = ['rating']

        # reformat styles for JS
        inits['styles'].val = ', '.join([
            "visual.Slider.Style.{}".format(sliderStyles[style])
            for style in inits['styles'].val
        ])
        # add comma so is treated as tuple in py2js and converted to list, as required
        inits['styles'].val += ','
        inits['styles'].val = py2js.expression2js(inits['styles'].val)

        # build up an initialization string for Slider():
        initStr = (
            "{name} = new visual.Slider({{\n"
            "  win: psychoJS.window, name: '{name}',\n"
            "  size: {size}, pos: {pos},\n"
            "  labels: {labels}, ticks: {ticks},\n"
            "  granularity: {granularity}, style: {styles},\n"
            "  color: new util.Color({color}), \n"
            "  fontFamily: {font}, bold: true, italic: false, \n").format(
                **inits)
        initStr += ("  flip: {flip},\n"
                    "}});\n\n").format(flip=boolConverter[inits['flip'].val])
        buff.writeIndentedLines(initStr)
Exemplo n.º 6
0
    def writeInitCodeJS(self, buff):
        inits = getInitVals(self.params)
        for param in inits:
            if inits[param].val in ['', None, 'None', 'none']:
                inits[param].val = 'undefined'
        boolConverter = {False: 'false', True: 'true'}
        sliderStyles = {'slider': 'SLIDER',
                        '()': 'RATING',
                        'rating': 'RATING',
                        'radio': 'RADIO',
                        'labels45': 'LABELS_45',
                        'whiteOnBlack': 'WHITE_ON_BLACK',
                        'triangleMarker': 'TRIANGLE_MARKER'}

        # If no style given, set default 'rating' as list
        if len(inits['styles'].val) == 0:
            inits['styles'].val = ['rating']

        # reformat styles for JS
        inits['styles'].val = ', '.join(["visual.Slider.Style.{}".
                                        format(sliderStyles[style]) for style in inits['styles'].val])
        # add comma so is treated as tuple in py2js and converted to list, as required
        inits['styles'].val += ','
        inits['styles'].val = py2js.expression2js(inits['styles'].val)

        # build up an initialization string for Slider():
        initStr = ("{name} = new visual.Slider({{\n"
                   "  win: psychoJS.window, name: '{name}',\n"
                   "  size: {size}, pos: {pos},\n"
                   "  labels: {labels}, ticks: {ticks},\n"
                   "  granularity: {granularity}, style: {styles},\n"
                   "  color: new util.Color({color}), \n"
                   "  fontFamily: {font}, bold: true, italic: false, \n"
                   ).format(**inits)
        initStr += ("  flip: {flip},\n"
                    "}});\n\n").format(flip=boolConverter[inits['flip'].val])
        buff.writeIndentedLines(initStr)
Exemplo n.º 7
0
def getInitVals(params, target="PsychoPy"):
    """Works out a suitable initial value for a parameter (e.g. to go into the
    __init__ of a stimulus object, avoiding using a variable name if possible
    """
    inits = copy.deepcopy(params)
    for name in params:
        if target == "PsychoJS":
            # convert (0,0.5) to [0,0.5] but don't convert "rand()" to "rand[]" and don't convert text
            valStr = str(inits[name].val).strip()
            if valStr.startswith("(") and valStr.endswith(
                    ")") and name != 'text':
                inits[name].val = py2js.expression2js(inits[name].val)
            # filenames (e.g. for image) need to be loaded from resources
            if name in ["sound"]:
                val = str(inits[name].val)
                if val not in [None, 'None', 'none', '']:
                    inits[name].val = (
                        "psychoJS.resourceManager.getResource({})".format(
                            inits[name]))
                    inits[name].valType = 'code'

        if not hasattr(inits[name],
                       'updates'):  # might be settings parameter instead
            continue

        # value should be None (as code)
        elif inits[name].val in [None, 'None', 'none', '']:
            if name in ['text']:
                inits[name].val = None
                inits[name].valType = 'extendedStr'
            else:
                inits[name].val = 'None'
                inits[name].valType = 'code'

        # is constant so don't touch the parameter value
        elif inits[name].updates in ['constant', None, 'None']:
            continue  # things that are constant don't need handling

        # is changing so work out a reasonable default
        elif name in ['pos', 'fieldPos']:
            inits[name].val = '[0,0]'
            inits[name].valType = 'code'
        elif name in [
                'color', 'foreColor', 'borderColor', 'lineColor', 'fillColor'
        ]:
            inits[name].val = 'white'
            inits[name].valType = 'str'
        elif name in [
                'ori',
                'sf',
                'size',
                'height',
                'letterHeight',
                'lineWidth',
                'phase',
                'opacity',
                'volume',  # sounds
                'coherence',
                'nDots',
                'fieldSize',
                'dotSize',
                'dotLife',
                'dir',
                'speed',
                'contrast',
                'moddepth',
                'envori',
                'envphase',
                'envsf',
                'noiseClip',
                'noiseBWO',
                'noiseFilterUpper',
                'noiseFilterLower',
                'noiseBaseSf',
                'noiseBW',
                'noiseElementSize',
                'noiseFilterOrder',
                'noiseFractalPower'
        ]:
            inits[name].val = "1.0"
            inits[name].valType = 'code'
        elif name in ['image', 'mask', 'envelope', 'carrier']:
            inits[name].val = "sin"
            inits[name].valType = 'str'
        elif name == 'texture resolution':
            inits[name].val = "128"
            inits[name].valType = 'code'
        elif name == 'colorSpace':
            inits[name].val = "rgb"
            inits[name].valType = 'str'
        elif name == 'font':
            inits[name].val = "Arial"
            inits[name].valType = 'str'
        elif name == 'units':
            inits[name].val = "norm"
            inits[name].valType = 'str'
        elif name == 'text':
            inits[name].val = ""
            inits[name].valType = 'str'
        elif name == 'flip':
            inits[name].val = ""
            inits[name].valType = 'str'
        elif name == 'sound':
            inits[name].val = "A"
            inits[name].valType = 'str'
        elif name == 'blendmode':
            inits[name].val = "avg"
            inits[name].valType = 'str'
        elif name == 'beat':
            inits[name].val = "False"
            inits[name].valType = 'str'
        elif name == 'noiseImage':
            inits[name].val = "None"
            inits[name].valType = 'str'
        elif name == 'noiseType':
            inits[name].val = 'Binary'
            inits[name].valType = 'str'
        elif name == 'marker_label':
            inits[name].val = 'Label'
            inits[name].valType = 'str'
        elif name == 'marker_value':
            inits[name].val = 'Value'
            inits[name].valType = 'str'
        elif name == 'buttonRequired':
            inits[name].val = "True"
            inits[name].valType = 'code'
        elif name == 'vertices':
            inits[
                name].val = "[[-0.5,-0.5], [-0.5, 0.5], [0.5, 0.5], [0.5, -0.5]]"
            inits[name].valType = 'code'
        else:
            print("I don't know the appropriate default value for a '%s' "
                  "parameter. Please email the mailing list about this error" %
                  name)

    return inits
Exemplo n.º 8
0
def getInitVals(params, target="PsychoPy"):
    """Works out a suitable initial value for a parameter (e.g. to go into the
    __init__ of a stimulus object, avoiding using a variable name if possible
    """
    inits = copy.deepcopy(params)
    for name in params:

        if target == "PsychoJS":
            # convert (0,0.5) to [0,0.5] but don't convert "rand()" to "rand[]"
            valStr = str(inits[name].val).strip()

            if valStr.startswith("(") and valStr.endswith(")"):
                inits[name].val = py2js.expression2js(inits[name].val)
            # filenames (e.g. for image) need to be loaded from resources
            if name in ["sound"]:
                val = str(inits[name].val)
                if val not in [None, 'None', 'none', '']:
                    inits[name].val = ("psychoJS.resourceManager.getResource({})"
                                       .format(inits[name]))
                    inits[name].valType = 'code'

        if not hasattr(inits[name], 'updates'):  # might be settings parameter instead
            continue

        # value should be None (as code)
        elif inits[name].val in [None, 'None', 'none', '']:
            inits[name].val = 'None'
            inits[name].valType = 'code'

        # is constant so don't touch the parameter value
        elif inits[name].updates in ['constant', None, 'None']:
            continue  # things that are constant don't need handling

        # is changing so work out a reasonable default
        elif name in ['pos', 'fieldPos']:
            inits[name].val = '[0,0]'
            inits[name].valType = 'code'
        elif name is 'color':
            inits[name].val = 'white'
            inits[name].valType = 'str'
        elif name in ['ori', 'sf', 'size', 'height', 'letterHeight',
                      'lineColor', 'fillColor',
                      'phase', 'opacity',
                      'volume',  # sounds
                      'coherence', 'nDots', 'fieldSize', 'dotSize', 'dotLife',
                      'dir', 'speed',
                      'contrast', 'moddepth', 'envori', 'envphase', 'envsf',
                      'noiseClip', 'noiseBWO', 'noiseFilterUpper', 'noiseFilterLower',
                      'noiseBaseSf', 'noiseBW', 'noiseElementSize', 'noiseFilterOrder',
                      'noiseFractalPower']:
            inits[name].val = "1.0"
            inits[name].valType = 'code'
        elif name in ['image', 'mask', 'envelope', 'carrier']:
            inits[name].val = "sin"
            inits[name].valType = 'str'
        elif name == 'texture resolution':
            inits[name].val = "128"
            inits[name].valType = 'code'
        elif name == 'colorSpace':
            inits[name].val = "rgb"
            inits[name].valType = 'str'
        elif name == 'font':
            inits[name].val = "Arial"
            inits[name].valType = 'str'
        elif name == 'units':
            inits[name].val = "norm"
            inits[name].valType = 'str'
        elif name == 'text':
            inits[name].val = "default text"
            inits[name].valType = 'str'
        elif name == 'flip':
            inits[name].val = ""
            inits[name].valType = 'str'
        elif name == 'sound':
            inits[name].val = "A"
            inits[name].valType = 'str'
        elif name == 'blendmode':
            inits[name].val = "avg"
            inits[name].valType = 'str'
        elif name == 'beat':
            inits[name].val = "False"
            inits[name].valType = 'str'
        elif name == 'noiseImage':
            inits[name].val = "None"
            inits[name].valType = 'str'
        elif name == 'noiseType':
            inits[name].val = 'Binary'
            inits[name].valType = 'str'
        else:
            print("I don't know the appropriate default value for a '%s' "
                  "parameter. Please email the mailing list about this error" %
                  name)

    return inits