def test_refresh_rate(self):
     if self.win.winType=='pygame':
         pytest.skip("getMsPerFrame seems to crash the testing of pygame")
     #make sure that we're successfully syncing to the frame rate
     msPFavg, msPFstd, msPFmed = visual.getMsPerFrame(self.win,nFrames=60, showVisual=True)
     assert (1000/150.0 < msPFavg < 1000/40.0), \
         "Your frame period is %.1fms which suggests you aren't syncing to the frame" %msPFavg
Exemple #2
0
 def test_refresh_rate(self):
     if self.win.winType=='pygame':
         pytest.skip("getMsPerFrame seems to crash the testing of pygame")
     #make sure that we're successfully syncing to the frame rate
     msPFavg, msPFstd, msPFmed = visual.getMsPerFrame(self.win,nFrames=60, showVisual=True)
     assert (1000/150.0 < msPFavg < 1000/40.0), \
         "Your frame period is %.1fms which suggests you aren't syncing to the frame" %msPFavg
Exemple #3
0
def launch_window(params, test_refresh=True, test_tol=.5):
    """Open up a presentation window and measure the refresh rate."""
    # Get the monitor parameters
    m = WindowInfo(params)
    stated_refresh_hz = getattr(m, "refresh_hz", None)

    # Initialize the Psychopy window object
    win = visual.Window(**m.window_kwargs)

    # Record the refresh rate we are currently achieving
    if test_refresh or stated_refresh_hz is None:
        win.setRecordFrameIntervals(True)
        logging.console.setLevel(logging.CRITICAL)
        flip_time, _, _ = visual.getMsPerFrame(win)
        observed_refresh_hz = 1000 / flip_time

    # Possibly test the refresh rate against what we expect
    if test_refresh and stated_refresh_hz is not None:
        refresh_error = np.abs(stated_refresh_hz - observed_refresh_hz)
        if refresh_error > test_tol:
            msg = ("Observed refresh rate differs from expected by {:.3f} Hz"
                   .format(refresh_error))
            raise RuntimeError(msg)

    # Set the refresh rate to use in the experiment
    if stated_refresh_hz is None:
        msg = "Monitor configuration does not have refresh rate information"
        warnings.warn(msg)
        win.refresh_hz = observed_refresh_hz
    else:
        win.refresh_hz = stated_refresh_hz

    return win
Exemple #4
0
 def testRefreshRate(self):
     if self.win.winType == "pygame":
         raise nose.plugins.skip.SkipTest("getMsPerFrame seems to crash the testing of pygame")
     # make sure that we're successfully syncing to the frame rate
     msPFavg, msPFstd, msPFmed = visual.getMsPerFrame(self.win, nFrames=60, showVisual=True)
     nose.tools.ok_(
         1000 / 150.0 < msPFavg < 1000 / 40.0,
         "Your frame period is %.1fms which suggests you aren't syncing to the frame" % msPFavg,
     )
Exemple #5
0
 def test_refresh_rate(self):
     if self.win.winType == "pygame":
         pytest.skip("getMsPerFrame seems to crash the testing of pygame")
     # make sure that we're successfully syncing to the frame rate
     msPFavg, msPFstd, msPFmed = visual.getMsPerFrame(self.win, nFrames=60, showVisual=True)
     utils.skip_under_travis()  # skip late so we smoke test the code
     assert 1000 / 150.0 < msPFavg < 1000 / 40.0, (
         "Your frame period is %.1fms which suggests you aren't syncing to the frame" % msPFavg
     )
Exemple #6
0
    def _setWindowInfo(self, win, verbose=False, refreshTest='grating', usingTempWin=True):
        """find and store info about the window: refresh rate, configuration info
        """

        if refreshTest in ['grating', True]:
            msPFavg, msPFstd, msPFmd6 = visual.getMsPerFrame(win, nFrames=120,
                                                             showVisual=bool(refreshTest == 'grating'))
            self['windowRefreshTimeAvg_ms'] = msPFavg
            self['windowRefreshTimeMedian_ms'] = msPFmd6
            self['windowRefreshTimeSD_ms'] = msPFstd
        if usingTempWin:
            return

        # These 'configuration lists' control what attributes are reported.
        # All desired attributes/properties need a legal internal name, e.g., win.winType.
        # If an attr is callable, its gets called with no arguments, e.g., win.monitor.getWidth()
        winAttrList = ['winType', '_isFullScr', 'units', 'monitor', 'pos', 'screen', 'rgb', 'size']
        winAttrListVerbose = ['allowGUI', 'useNativeGamma', 'recordFrameIntervals',
                              'waitBlanking', '_haveShaders', '_refreshThreshold']
        if verbose: winAttrList += winAttrListVerbose

        monAttrList = ['name', 'getDistance', 'getWidth', 'currentCalibName']
        monAttrListVerbose = ['_gammaInterpolator', '_gammaInterpolator2']
        if verbose:
            monAttrList += monAttrListVerbose
        if 'monitor' in winAttrList:  # replace 'monitor' with all desired monitor.<attribute>
            i = winAttrList.index('monitor')  # retain list-position info, put monitor stuff there
            del winAttrList[i]
            for monAttr in monAttrList:
                winAttrList.insert(i, 'monitor.' + monAttr)
                i += 1
        for winAttr in winAttrList:
            try:
                attrValue = eval('win.' + winAttr)
            except AttributeError:
                logging.warning('AttributeError in RuntimeInfo._setWindowInfo(): Window instance has no attribute', winAttr)
                continue
            if hasattr(attrValue, '__call__'):
                try:
                    a = attrValue()
                    attrValue = a
                except:
                    print 'Warning: could not get a value from win.' + winAttr + '()  (expects arguments?)'
                    continue
            while winAttr[0] == '_':
                winAttr = winAttr[1:]
            winAttr = winAttr[0].capitalize() + winAttr[1:]
            winAttr = winAttr.replace('Monitor._', 'Monitor.')
            if winAttr in ['Pos', 'Size']:
                winAttr += '_pix'
            if winAttr in ['Monitor.getWidth', 'Monitor.getDistance']:
                winAttr += '_cm'
            if winAttr in ['RefreshThreshold']:
                winAttr += '_sec'
            self['window' + winAttr] = attrValue
Exemple #7
0
    def _setWindowInfo(self, win, verbose=False, refreshTest='grating', usingTempWin=True):
        """find and store info about the window: refresh rate, configuration info
        """

        if refreshTest in ['grating', True]:
            msPFavg, msPFstd, msPFmd6 = visual.getMsPerFrame(win, nFrames=120,
                                                             showVisual=bool(refreshTest == 'grating'))
            self['windowRefreshTimeAvg_ms'] = msPFavg
            self['windowRefreshTimeMedian_ms'] = msPFmd6
            self['windowRefreshTimeSD_ms'] = msPFstd
        if usingTempWin:
            return

        # These 'configuration lists' control what attributes are reported.
        # All desired attributes/properties need a legal internal name, e.g., win.winType.
        # If an attr is callable, its gets called with no arguments, e.g., win.monitor.getWidth()
        winAttrList = ['winType', '_isFullScr', 'units', 'monitor', 'pos', 'screen', 'rgb', 'size']
        winAttrListVerbose = ['allowGUI', 'useNativeGamma', 'recordFrameIntervals',
                              'waitBlanking', '_haveShaders', '_refreshThreshold']
        if verbose: winAttrList += winAttrListVerbose

        monAttrList = ['name', 'getDistance', 'getWidth', 'currentCalibName']
        monAttrListVerbose = ['getGammaGrid','getLinearizeMethod','_gammaInterpolator', '_gammaInterpolator2']
        if verbose:
            monAttrList += monAttrListVerbose
        if 'monitor' in winAttrList:  # replace 'monitor' with all desired monitor.<attribute>
            i = winAttrList.index('monitor')  # retain list-position info, put monitor stuff there
            del winAttrList[i]
            for monAttr in monAttrList:
                winAttrList.insert(i, 'monitor.' + monAttr)
                i += 1
        for winAttr in winAttrList:
            try:
                attrValue = eval('win.' + winAttr)
            except AttributeError:
                logging.warning('AttributeError in RuntimeInfo._setWindowInfo(): Window instance has no attribute', winAttr)
                continue
            if hasattr(attrValue, '__call__'):
                try:
                    a = attrValue()
                    attrValue = a
                except:
                    print 'Warning: could not get a value from win.' + winAttr + '()  (expects arguments?)'
                    continue
            while winAttr[0] == '_':
                winAttr = winAttr[1:]
            winAttr = winAttr[0].capitalize() + winAttr[1:]
            winAttr = winAttr.replace('Monitor._', 'Monitor.')
            if winAttr in ['Pos', 'Size']:
                winAttr += '_pix'
            if winAttr in ['Monitor.getWidth', 'Monitor.getDistance']:
                winAttr += '_cm'
            if winAttr in ['RefreshThreshold']:
                winAttr += '_sec'
            self['window' + winAttr] = attrValue
Exemple #8
0
 def testRefreshRate(self):
     if self.win.winType == 'pygame':
         raise nose.plugins.skip.SkipTest(
             "getMsPerFrame seems to crash the testing of pygame")
     #make sure that we're successfully syncing to the frame rate
     msPFavg, msPFstd, msPFmed = visual.getMsPerFrame(self.win,
                                                      nFrames=60,
                                                      showVisual=True)
     nose.tools.ok_(
         1000 / 150.0 < msPFavg < 1000 / 40.0,
         "Your frame period is %.1fms which suggests you aren't syncing to the frame"
         % msPFavg)
Exemple #9
0
    def runDiagnostics(self, win, verbose=False):
        """Return list of (key, val, msg) tuple, set self.warnings

        All tuple elements will be of <type str>.

        msg can depend on val; msg starts with 'Warning:' to indicate a concern.
        Plain text is returned, expected to be used in html <table>.
        Hyperlinks can be embedded as <a href="...">
        """

        report = []  # add item tuples in display order

        # get lots of info and do quick-to-render visual (want no frames drop):
        #     for me, grating draw times are: mean 0.53 ms, SD 0.77 ms
        items = info.RunTimeInfo(win=win, refreshTest='grating', verbose=True, userProcsDetailed=True)

        totalRAM, freeRAM = items['systemMemTotalRAM'], items['systemMemFreeRAM']
        if freeRAM == 'unknown':
            if totalRAM != 'unknown':
                totalRAM = "%.1fG" % (totalRAM / 1024.)
            msg = 'could not assess available physical RAM; total %s' % totalRAM
            report.append(('available memory', 'unknown', msg))
        else:
            msg = 'physical RAM available for configuration test (of %.1fG total)' % (totalRAM / 1024.)
            if freeRAM < 300:  # in M
                msg = 'Warning: low available physical RAM for configuration test (of %.1fG total)' % (totalRAM / 1024.)
            report.append(('available memory', str(freeRAM)+'M', msg))

        # ----- PSYCHOPY: -----
        report.append(('PsychoPy', '', ''))
        report.append(('psychopy', __version__, 'avoid upgrading during an experiment'))
        report.append(('locale', items['systemLocale'], 'can be set in <a href="http://www.psychopy.org/general/prefs.html#application-settings">Preferences -> App</a>'))
        msg = ''
        if items['pythonVersion'] < '2.5' or items['pythonVersion'] >= '3':
            msg = 'Warning: python 2.5, 2.6, or 2.7 required; 2.5 is iffy'
        if 'EPD' in items['pythonFullVersion']:
            msg += ' Enthought Python Distribution'
        elif 'PsychoPy2.app' in items['pythonExecutable']:
            msg += ' (PsychoPy StandAlone)'
        bits, linkage = platform.architecture()
        if not bits.startswith('32'):
            msg = 'Warning: 32-bit python required; ' + msg
        report.append(('python version', items['pythonVersion'] + ' &nbsp;(%s)' % bits, msg))
        if verbose:
            msg = ''
            if items['pythonWxVersion'] < '2.8.10':
                msg = 'Warning: wx 2.8.10 or higher required'
            report.append(('wx', items['pythonWxVersion'], ''))
            report.append(('pyglet', items['pythonPygletVersion'][:32], ''))
            report.append(('rush', str(items['psychopyHaveExtRush']), 'for high-priority threads'))

        # ----- VISUAL: -----
        report.append(('Visual', '', ''))
        # openGL settings:
        msg = ''
        if items['openGLVersion'] < '2.':
            msg = 'Warning: <a href="http://www.psychopy.org/general/timing/reducingFrameDrops.html?highlight=OpenGL+2.0">OpenGL 2.0 or higher is ideal</a>.'
        report.append(('openGL version', items['openGLVersion'], msg))
        report.append(('openGL vendor', items['openGLVendor'], ''))
        report.append(('screen size', ' x '.join(map(str, items['windowSize_pix'])), ''))
        #report.append(('wait blanking', str(items['windowWaitBlanking']), ''))

        msg = ''
        if not items['windowHaveShaders']:
            msg = 'Warning: <a href="http://www.psychopy.org/general/timing/reducingFrameDrops.html?highlight=shader">Rendering of complex stimuli will be slow</a>.'
        report.append(('have shaders', str(items['windowHaveShaders']), msg))

        msg = 'during the drifting <a href="http://www.psychopy.org/api/visual/gratingstim.html">GratingStim</a>'
        if items['windowRefreshTimeMedian_ms'] < 3.3333333:
            msg = """Warning: too fast? visual sync'ing with the monitor seems unlikely at 300+ Hz"""
        report.append(('visual sync (refresh)', "%.2f ms/frame" % items['windowRefreshTimeMedian_ms'], msg))
        msg = 'SD < 0.5 ms is ideal (want low variability)'
        if items['windowRefreshTimeSD_ms'] > .5:
            msg = 'Warning: the refresh rate has high frame-to-frame variability (SD > 0.5 ms)'
        report.append(('refresh stability (SD)', "%.2f ms" % items['windowRefreshTimeSD_ms'], msg))

        # draw 100 dots as a minimally demanding visual test:
        # first get baseline frame-rate (safe as possible, no drawing):
        avg, sd, median = visual.getMsPerFrame(win)
        dots100 = visual.DotStim(win, nDots=100, speed=0.005, dotLife=12, dir=90,
            coherence=0.2, dotSize=8, fieldShape='circle')
        win.setRecordFrameIntervals(True)
        win.frameIntervals = []
        win.flip()
        for i in xrange(180):
            dots100.draw()
            win.flip()
        msg = 'during <a href="http://www.psychopy.org/api/visual/dotstim.html">DotStim</a> with 100 random dots'
        intervalsMS = np.array(win.frameIntervals) * 1000
        nTotal = len(intervalsMS)
        nDropped = sum(intervalsMS > (1.5 * median))
        if nDropped:
            msg = 'Warning: could not keep up during <a href="http://www.psychopy.org/api/visual/dotstim.html">DotStim</a> with 100 random dots.'
        report.append(('no dropped frames', '%i / %i' % (nDropped, nTotal), msg))
        win.setRecordFrameIntervals(False)
        try:
            from pyglet.media import avbin
            ver = avbin.get_version()
            if ver < 5 or ver >= 6:
                msg = 'Warning: version 5 recommended (for movies); Visit <a href="http://code.google.com/p/avbin">download page</a> [google.com]'
            else:
                msg = 'for movies'
            report.append(('pyglet avbin', str(ver), msg))
        except: # not sure what error to catch, WindowsError not found
            report.append(('pyglet avbin', 'import error', 'Warning: could not import avbin; playing movies will not work'))

        if verbose:
            report.append(('openGL max vertices', str(items['openGLmaxVerticesInVertexArray']), ''))
            keyList = ['GL_ARB_multitexture', 'GL_EXT_framebuffer_object', 'GL_ARB_fragment_program',
                'GL_ARB_shader_objects', 'GL_ARB_vertex_shader', 'GL_ARB_texture_non_power_of_two',
                'GL_ARB_texture_float', 'GL_STEREO']
            for key in keyList:
                val = items['openGLext.'+key]  # boolean
                if not val:
                    val = '<strong>' + str(val) + '</strong>'
                report.append((key, str(val), ''))

        # ----- AUDIO: -----
        report.append(('Audio', '', ''))
        msg = ''
        if not 'systemPyoVersion' in items:
            msg = 'Warning: pyo is needed for sound and microphone.'
            items['systemPyoVersion'] = '(missing)'
        elif items['systemPyoVersion'] < '0.6.2':
            msg = 'pyo 0.6.2 compiled with --no-messages will suppress start-up messages'
        report.append(('pyo', items['systemPyoVersion'], msg))
        # sound latencies from portaudio; requires pyo svn r1024
        try:
            sndInputDevices = items['systemPyo.InputDevices']
            if len(sndInputDevices.keys()):
                key = sndInputDevices.keys()[0]
                mic = sndInputDevices[key]
                if mic['name'].endswith('icroph'):
                    mic['name'] += 'one'  # portaudio (?) seems to clip to 16 chars
                msg = '"%s"' % mic['name']
                if mic['latency'] > 0.003:
                    msg = 'Warning: "%s" latency > 3ms' % mic['name']
                report.append(('microphone latency', "%.4f s" % mic['latency'], msg))
            else:
                report.append(('microphone', '(not detected)',''))
            sndOutputDevices = items['systemPyo.OutputDevices']
            if len(sndOutputDevices.keys()):
                key = sndOutputDevices.keys()[0]
                spkr = sndOutputDevices[key]
                msg = '"%s"' % spkr['name']
                if spkr['latency'] > 0.003:
                    msg = 'Warning: "%s" latency > 3ms' % spkr['name']
                report.append(('speakers latency', "%.4f s" % spkr['latency'], msg))
            else:
                report.append(('speakers', '(not detected)',''))
        except KeyError:
            pass
        s2t = '<a href="http://www.psychopy.org/api/microphone.html?highlight=Speech2Text">speech-to-text</a>'
        msg = 'audio codec for %s' % s2t
        if not 'systemFlacVersion' in items:
            msg = 'Warning: flac is needed for using %s features. <a href="http://flac.sourceforge.net/download.html">Download</a> [sourceforge.net].' % s2t
            items['systemFlacVersion'] = '(missing)'
        if verbose:
            report.append(('flac', items['systemFlacVersion'].lstrip('flac '), msg))
        # TO-DO: add microphone + playback as sound test

        # ----- NUMERIC: -----
        report.append(('Numeric', '', ''))
        report.append(('numpy', items['pythonNumpyVersion'], 'vector-based (fast) calculations'))
        report.append(('scipy', items['pythonScipyVersion'], 'scientific / numerical'))
        report.append(('matplotlib', items['pythonMatplotlibVersion'], 'plotting; fast contains(), overlaps()'))

        # ----- SYSTEM: -----
        report.append(('System', '', ''))
        report.append(('platform', items['systemPlatform'], ''))
        msg = 'for online help, usage statistics, software updates, and google-speech'
        if items['systemHaveInternetAccess'] is not True:
            items['systemHaveInternetAccess'] = 'False'
            msg = 'Warning: could not connect (no proxy attempted)'
            # TO-DO: dlg to query whether to try to auto-detect (can take a while), or allow manual entry of proxy str, save into prefs
        val = str(items['systemHaveInternetAccess'])
        report.append(('internet access', val, msg))
        report.append(('auto proxy', str(self.prefs.connections['autoProxy']), 'try to auto-detect a proxy if needed; see <a href="http://www.psychopy.org/general/prefs.html#connection-settings">Preferences -> Connections</a>'))
        if not self.prefs.connections['proxy'].strip():
            prx = '&nbsp;&nbsp--'
        else:
            prx = str(self.prefs.connections['proxy'])
        report.append(('proxy setting', prx, 'current manual proxy setting from <a href="http://www.psychopy.org/general/prefs.html#connection-settings">Preferences -> Connections</a>'))

        msg = ''
        items['systemUserProcFlagged'].sort()
        self.badBgProc = [p for p,pid in items['systemUserProcFlagged']]
        val = ("%s ..." % self.badBgProc[0]) if len(self.badBgProc) else 'No bad background processes found.'
        msg = 'Warning: Some <a href="http://www.psychopy.org/general/timing/reducingFrameDrops.html?highlight=background+processes">background processes</a> can adversely affect timing'
        report.append(('background processes', val, msg))
        if verbose and 'systemSec.OpenSSLVersion' in items:
            report.append(('OpenSSL', items['systemSec.OpenSSLVersion'].lstrip('OpenSSL '), 'for <a href="http://www.psychopy.org/api/encryption.html">encryption</a>'))
        report.append(('CPU speed test', "%.3f s" % items['systemTimeNumpySD1000000_sec'], 'numpy.std() of a million data points'))
            # TO-DO: more speed benchmarks
            # - load large image file from disk
            # - transfer image to GPU

        # ----- IMPORTS (relevant for developers & non-StandAlone): -----
        if verbose:  # always False for a real first-run
            report.append(('Packages', '', ''))
            packages = ['PIL', 'openpyxl', 'lxml', 'setuptools', 'pytest', 'sphinx',
                        'psignifit', 'pyserial', 'pp',
                        'pynetstation', 'ioLabs', 'labjack'
                        ]
            if sys.platform == 'win32':
                packages.append('pywin32')
                packages.append('winioport')
            for pkg in packages:
                try:
                    if pkg == 'PIL':
                        exec('import PIL.Image')
                        ver = PIL.Image.VERSION
                    #elif pkg == 'lxml':
                    #
                    elif pkg == 'pp':
                        exec('import pp; ver = pp.version')
                    elif pkg == 'pynetstation':
                        exec('from psychopy.hardware import egi')
                        ver = 'import ok'
                    elif pkg == 'pyserial':
                        exec('import serial')
                        ver = serial.VERSION
                    else:
                        exec('import ' + pkg)
                        try: ver = eval(pkg+'.__version__')
                        except: ver = 'import ok'
                    report.append((pkg, ver, ''))
                except (ImportError, AttributeError):
                    report.append((pkg, '&nbsp;&nbsp--', 'could not import %s' % pkg))

        self.warnings = list(set([key for key, val, msg in report if msg.startswith('Warning')]))
        return report
Exemple #10
0
 def testRefreshRate(self):
     #make sure that we're successfully syncing to the frame rate
     msPFavg, msPFstd, msPFmed = visual.getMsPerFrame(self.win,nFrames=60, showVisual=True)
     nose.tools.ok_(1000/150.0 < msPFavg < 1000/40.0, "Your frame period is %.1fms which suggests you aren't syncing to the frame" %msPFavg)
Exemple #11
0
    def launch_window(self, test_refresh=True, test_tol=.5):
        """Load window info"""
        #taken from Mwaskom cregg
        try:
            mod = __import__("monitors")
        except ImportError:
            sys.exit("Could not import monitors.py in this directory.")

        try:
            minfo = getattr(mod, self.monitor_name)
        except IndexError:
            sys.exit("Monitor not found in monitors.py")

        fullscreen = self.full_screen
        size = minfo["size"] if fullscreen else (800, 600)

        monitor = Monitor(name=minfo["name"],
                          width=minfo["width"],
                          distance=minfo["distance"])
        monitor.setSizePix(minfo["size"])

        info = dict(units=self.monitor_units,
                    fullscr=fullscreen,
                    color=self.window_color,
                    size=size,
                    monitor=monitor)

        if "framerate" in minfo:
            self.framerate = minfo["framerate"]

        self.name = self.monitor_name
        self.__dict__.update(info)
        self.window_kwargs = info
        """Open up a presentation window and measure the refresh rate."""
        stated_refresh_hz = self.framerate

        # Initialize the Psychopy window object
        win = visual.Window(**self.window_kwargs)

        # Record the refresh rate we are currently achieving
        if self.test_refresh or stated_refresh_hz is None:
            win.setRecordFrameIntervals(True)
            logging.console.setLevel(logging.CRITICAL)
            flip_time, _, _ = visual.getMsPerFrame(win)
            observed_refresh_hz = 1000 / flip_time
            print('observed_refresh_hz', observed_refresh_hz)

        # Possibly test the refresh rate against what we expect
        if self.test_refresh and stated_refresh_hz is not None:
            refresh_error = np.abs(stated_refresh_hz - observed_refresh_hz)
            print('refresh_error', refresh_error)
            if refresh_error > test_tol:
                msg = (
                    "Observed refresh rate differs from expected by {:.3f} Hz".
                    format(refresh_error))
                raise RuntimeError(msg)

        # Set the refresh rate to use in the experiment
        if stated_refresh_hz is None:
            msg = "Monitor configuration does not have refresh rate information"
            warnings.warn(msg)
            win.framerate = observed_refresh_hz
        else:
            win.framerate = stated_refresh_hz

        return win
Exemple #12
0
    def __init__(self, exp_info, file_name):
        """
        Initialize experiment - read XML file, setup window, connect to netstation and tobii
        exp_info - experiment information
        file_name - name of XML file containing experiment definition
        """
        self.exp_info = exp_info
        self.name = None
        self.type = None
        self.num_blocks = 0
        self.blocks = {}
        self.block_order = []

        # Window to use
        wintype = 'pyglet'  # use pyglet if possible, it's faster at event handling
        # Add 14cm to distance - this is distance from eyetracker to monitor
        mon = monitors.Monitor(exp_info['monitor'], distance=float(exp_info['monitor distance']))
        self.win = Window(
            [1280, 1024],
            monitor=mon,
            screen=SCREEN,
            units="deg",
            fullscr=True,
            #fullscr=False,
            color=[-1, -1, -1],
            winType=wintype)
        self.win.setMouseVisible(False)
        event.clearEvents()

        # Measure frame rate
        self.mean_ms_per_frame, std_ms_per_frame, median_ms_per_frame = visual.getMsPerFrame(self.win, nFrames=60,
                                                                                             showVisual=True)

        self.debug_sq=None
        if exp_info['monitor']=='tobii':
            self.debug_sq=psychopy.visual.Rect(self.win, width=30, height=30, units='pix')
            self.debug_sq.setFillColor((1,1,1))
            self.debug_sq.setPos((630,-500))

        # Compute distractor duration in frames based on frame rate
        distractor_duration_frames = int(2000.0/self.mean_ms_per_frame)

        # Initialize set of distractors
        self.distractor_set = DistractorSet(os.path.join(DATA_DIR, 'images', 'distractors', 'space'),
                                            os.path.join(DATA_DIR, 'sounds', 'distractors'),
                                            os.path.join(DATA_DIR, 'movies', 'distractors'),
                                            os.path.join(DATA_DIR, 'images', 'distractors', 'star-cartoon.jpg'),
                                            distractor_duration_frames, self.win)

        # Connect to nestation
        self.ns = None
        if exp_info['eeg']:
            # connect to netstation
            self.ns = egi.Netstation()
            ms_localtime = egi.ms_localtime

        self.eye_tracker = None
        mouse_visible = False
        if exp_info['eyetracking source'] == 'tobii':
            # Initialize eyetracker
            self.eye_tracker = TobiiController(self.win)
            self.eye_tracker.waitForFindEyeTracker()
            self.eye_tracker.activate(EYETRACKER_NAME)
        elif exp_info['eyetracking source'] == 'mouse':
            mouse_visible = True

        # Initialize mouse
        self.mouse = event.Mouse(visible=mouse_visible, win=self.win)

        self.gaze_debug=None
        if self.exp_info['debug mode']:
            self.gaze_debug=psychopy.visual.Circle(self.win, radius=1, fillColor=(1.0,-1.0,-1.0))

        self.read_xml(file_name)

        # Initialize netstation and eyetracker
        self.initialize()
Exemple #13
0
    def runDiagnostics(self, win, verbose=False):
        """Return list of (key, val, msg, warn) tuple, set self.warnings

        All tuple elements will be of <type str>.

        msg can depend on val; warn==True indicates a concern.
        Plain text is returned, expected to be used in html <table>.
        Hyperlinks can be embedded as <a href="...">
        """

        report = []  # add item tuples in display order

        # get lots of info and do quick-to-render visual (want no frames drop):
        #     for me, grating draw times are: mean 0.53 ms, SD 0.77 ms
        items = info.RunTimeInfo(win=win, refreshTest='grating', verbose=True, userProcsDetailed=True)

        totalRAM, freeRAM = items['systemMemTotalRAM'], items['systemMemFreeRAM']
        warn = False
        if freeRAM == 'unknown':
            if totalRAM != 'unknown':
                totalRAM = "%.1fG" % (totalRAM / 1024.)
            msg = _translate('could not assess available physical RAM; total %s') % totalRAM
            report.append(('available memory', 'unknown', msg, warn))
        else:
            msg = _translate('physical RAM available for configuration test (of %.1fG total)') % (totalRAM / 1024.)
            if freeRAM < 300:  # in M
                msg = _translate('Warning: low available physical RAM for configuration test (of %.1fG total)') % (totalRAM / 1024.)
                warn = True
            report.append(('available memory', unicode(freeRAM)+'M', msg, warn))

        # ----- PSYCHOPY: -----
        warn = False
        report.append(('PsychoPy', '', '', False))  # not localized
        report.append(('psychopy', __version__, _translate('avoid upgrading during an experiment'), False))
        report.append(('locale', items['systemLocale'],
                       _translate('can be set in <a href="http://www.psychopy.org/general/prefs.html#application-settings-app">Preferences -> App</a>'),
                       False))
        msg = ''
        if items['pythonVersion'] < '2.5' or items['pythonVersion'] >= '3':
            msg = _translate('Warning: python 2.6 or 2.7 required; 2.5 is not supported but might work')
            warn = True
        if 'EPD' in items['pythonFullVersion']:
            msg += ' Enthought Python Distribution'
        elif 'PsychoPy2.app' in items['pythonExecutable']:
            msg += ' (PsychoPy StandAlone)'
        bits, linkage = platform.architecture()
        #if not bits.startswith('32'):
        #    msg = 'Warning: 32-bit python required; ' + msg
        report.append(('python version', items['pythonVersion'] + ' &nbsp;(%s)' % bits, msg, warn))
        warn = False
        if verbose:
            msg = ''
            if items['pythonWxVersion'] < '2.8.10':
                msg = _translate('Warning: wx 2.8.10 or higher required')
                warn = True
            report.append(('wx', items['pythonWxVersion'], '', warn))
            report.append(('pyglet', items['pythonPygletVersion'][:32], '', False))
            report.append(('rush', str(items['psychopyHaveExtRush']), _translate('for high-priority threads'), False))

        # ----- VISUAL: -----
        report.append(('Visual', '', '', False))
        warn = False
        # openGL settings:
        msg = ''
        if items['openGLVersion'] < '2.':
            msg = _translate('Warning: <a href="http://www.psychopy.org/general/timing/reducingFrameDrops.html?highlight=OpenGL+2.0">OpenGL 2.0 or higher is ideal</a>.')
            warn = True
        report.append(('openGL version', items['openGLVersion'], msg, warn))
        report.append(('openGL vendor', items['openGLVendor'], '', False))
        report.append(('screen size', ' x '.join(map(str, items['windowSize_pix'])), '', False))
        #report.append(('wait blanking', str(items['windowWaitBlanking']), '', False))

        warn = False
        msg = ''
        if not items['windowHaveShaders']:
            msg = _translate('Warning: <a href="http://www.psychopy.org/general/timing/reducingFrameDrops.html?highlight=shader">Rendering of complex stimuli will be slow</a>.')
            warn = True
        report.append(('have shaders', str(items['windowHaveShaders']), msg, warn))

        warn = False
        msg = _translate('during the drifting <a href="http://www.psychopy.org/api/visual/gratingstim.html">GratingStim</a>')
        if items['windowRefreshTimeMedian_ms'] < 3.3333333:
            msg = _translate("""Warning: too fast? visual sync'ing with the monitor seems unlikely at 300+ Hz""")
            warn = True
        report.append(('visual sync (refresh)', "%.2f ms/frame" % items['windowRefreshTimeMedian_ms'], msg, warn))
        msg = _translate('SD &lt; 0.5 ms is ideal (want low variability)')
        warn = False
        if items['windowRefreshTimeSD_ms'] > .5:
            msg = _translate('Warning: the refresh rate has high frame-to-frame variability (SD &gt; 0.5 ms)')
            warn = True
        report.append(('refresh stability (SD)', "%.2f ms" % items['windowRefreshTimeSD_ms'], msg, warn))

        # draw 100 dots as a minimally demanding visual test:
        # first get baseline frame-rate (safe as possible, no drawing):
        avg, sd, median = visual.getMsPerFrame(win)
        dots100 = visual.DotStim(win, nDots=100, speed=0.005, dotLife=12, dir=90,
            coherence=0.2, dotSize=8, fieldShape='circle', autoLog=False)
        win.recordFrameIntervals = True
        win.frameIntervals = []
        win.flip()
        for i in xrange(180):
            dots100.draw()
            win.flip()
        msg = _translate('during <a href="http://www.psychopy.org/api/visual/dotstim.html">DotStim</a> with 100 random dots')
        warn = False
        intervalsMS = np.array(win.frameIntervals) * 1000
        nTotal = len(intervalsMS)
        nDropped = sum(intervalsMS > (1.5 * median))
        if nDropped:
            msg = _translate('Warning: could not keep up during <a href="http://www.psychopy.org/api/visual/dotstim.html">DotStim</a> with 100 random dots.')
            warn = True
        report.append(('no dropped frames', '%i / %i' % (nDropped, nTotal), msg, warn))
        win.recordFrameIntervals = False

        msg = _translate('for movies')
        warn = False
        try:
            from pyglet.media import avbin
        except: # not sure what error to catch, WindowsError not found
            report.append(('pyglet avbin', 'import error', _translate('Warning: could not import avbin; playing movies will not work'), True))
        else:
            ver = avbin.get_version()
            if sys.platform.startswith('linux'):
                if not (7 <= ver < 8):
                    msg = _translate('Warning: version 7 recommended on linux (for movies)')
                    warn = True
            elif not (5 <= ver < 6):
                msg = _translate('Warning: version 5 recommended (for movies); Visit <a href="http://code.google.com/p/avbin">download page</a> [google.com]')
                warn = True
            report.append(('pyglet avbin', unicode(ver), msg, warn))

        if verbose:
            report.append(('openGL max vertices', str(items['openGLmaxVerticesInVertexArray']), '', False))
            keyList = ['GL_ARB_multitexture', 'GL_EXT_framebuffer_object', 'GL_ARB_fragment_program',
                'GL_ARB_shader_objects', 'GL_ARB_vertex_shader', 'GL_ARB_texture_non_power_of_two',
                'GL_ARB_texture_float', 'GL_STEREO']
            for key in keyList:
                val = items['openGLext.'+key]  # boolean
                if not val:
                    val = '<strong>' + str(val) + '</strong>'
                report.append((key, str(val), '', False))

        # ----- AUDIO: -----
        report.append(('Audio', '', '', False))
        msg = ''
        warn = False
        if not 'systemPyoVersion' in items:
            msg = _translate('Warning: pyo is needed for sound and microphone.')
            warn = True
            items['systemPyoVersion'] = _translate('(missing)')
        #elif items['systemPyoVersion'] < '0.6.2':
        #    msg = 'pyo 0.6.2 compiled with --no-messages will suppress start-up messages'
        report.append(('pyo', items['systemPyoVersion'], msg, warn))
        # sound latencies from portaudio; requires pyo svn r1024
        try:
            sndInputDevices = items['systemPyo.InputDevices']
            warn = False
            if len(sndInputDevices.keys()):
                key = sndInputDevices.keys()[0]
                mic = sndInputDevices[key]
                if mic['name'].endswith('icroph'):
                    mic['name'] += 'one'  # portaudio (?) seems to clip to 16 chars
                msg = '"%s"' % mic['name']
                if mic['latency'] > 0.01:
                    msg = _translate('Warning: "%s" latency &gt; 10ms') % mic['name']
                    warn = True
                report.append(('microphone latency', "%.4f s" % mic['latency'], msg, warn))
            else:
                report.append(('microphone', _translate('(not detected)'),'', False))
            sndOutputDevices = items['systemPyo.OutputDevices']
            if len(sndOutputDevices.keys()):
                warn = False
                key = sndOutputDevices.keys()[0]
                spkr = sndOutputDevices[key]
                msg = '"%s"' % spkr['name']
                if spkr['latency'] > 0.01:
                    msg = _translate('Warning: "%s" latency &gt; 10ms') % spkr['name']
                    warn = True
                report.append(('speakers latency', "%.4f s" % spkr['latency'], msg, warn))
            else:
                report.append(('speakers', _translate('(not detected)'),'', False))
        except KeyError:
            pass
        s2t = '<a href="http://www.psychopy.org/api/microphone.html?highlight=Speech2Text">speech-to-text</a>'
        msg = _translate('audio codec for %s and sound file compression') % s2t
        warn = False
        if not 'systemFlacVersion' in items:
            msg = _translate('Warning: flac is needed for using %s and sound compression.') % s2t +\
                  ' <a href="http://flac.sourceforge.net/download.html">' +\
                  _translate('Download</a> [sourceforge.net].')
            warn = True
            items['systemFlacVersion'] = _translate('(missing)')
        if verbose:
            report.append(('flac', items['systemFlacVersion'].lstrip('flac '), msg, warn))
        # TO-DO: add microphone + playback as sound test

        # ----- NUMERIC: -----
        report.append(('Numeric', '', '', False))
        report.append(('numpy', items['pythonNumpyVersion'], _translate('vector-based (fast) calculations'), False))
        report.append(('scipy', items['pythonScipyVersion'], _translate('scientific / numerical'), False))
        report.append(('matplotlib', items['pythonMatplotlibVersion'], _translate('plotting; fast contains(), overlaps()'), False))

        # ----- SYSTEM: -----
        report.append(('System', '', '', False))
        report.append(('platform', items['systemPlatform'], '', False))
        msg = _translate('for online help, usage statistics, software updates, and google-speech')
        warn = False
        if items['systemHaveInternetAccess'] is not True:
            items['systemHaveInternetAccess'] = 'False'
            msg = _translate('Warning: could not connect (no proxy attempted)')
            warn = True
            # TO-DO: dlg to query whether to try to auto-detect (can take a while), or allow manual entry of proxy str, save into prefs
        val = str(items['systemHaveInternetAccess'])
        report.append(('internet access', val, msg, warn))
        report.append(('auto proxy', str(self.prefs.connections['autoProxy']), _translate('try to auto-detect a proxy if needed; see <a href="http://www.psychopy.org/general/prefs.html#connection-settings-connections">Preferences -> Connections</a>'), False))
        if not self.prefs.connections['proxy'].strip():
            prx = '&nbsp;&nbsp;--'
        else:
            prx = unicode(self.prefs.connections['proxy'])
        report.append(('proxy setting', prx, _translate('current manual proxy setting from <a href="http://www.psychopy.org/general/prefs.html#connection-settings-connections">Preferences -> Connections</a>'), False))

        msg = ''
        warn = False
        # assure that we have a list
        if items['systemUserProcFlagged'] is None:
            items['systemUserProcFlagged'] = []
        items['systemUserProcFlagged'].sort()
        self.badBgProc = [p for p,pid in items['systemUserProcFlagged']]
        if len(self.badBgProc):
            val = ("%s ..." % self.badBgProc[0])
            msg = _translate('Warning: Some <a href="http://www.psychopy.org/general/timing/reducingFrameDrops.html?highlight=background+processes">background processes</a> can adversely affect timing')
            warn = True
        else:
            val = _translate('No bad background processes active.')
        report.append(('background processes', val, msg, warn))
        if verbose and 'systemSec.OpenSSLVersion' in items:
            report.append(('OpenSSL', items['systemSec.OpenSSLVersion'].lstrip('OpenSSL '), 'for <a href="http://www.psychopy.org/api/encryption.html">encryption</a>', False))
        report.append(('CPU speed test', "%.3f s" % items['systemTimeNumpySD1000000_sec'], _translate('numpy.std() of 1,000,000 data points'), False))
            # TO-DO: more speed benchmarks
            # - load large image file from disk
            # - transfer image to GPU

        # ----- IMPORTS (relevant for developers & non-StandAlone): -----
        if verbose:  # always False for a real first-run
            report.append((_translate('Python packages'), '', '', False))
            packages = ['PIL', 'openpyxl', 'lxml', 'setuptools', 'pytest', 'sphinx',
                        'psignifit', 'pyserial', 'pp',
                        'pynetstation', 'ioLabs', 'labjack'
                        ]
            if sys.platform == 'win32':
                packages.append('pywin32')
                packages.append('winioport')
            for pkg in packages:
                try:
                    if pkg == 'PIL':
                        exec('import PIL.Image')
                        ver = PIL.Image.VERSION
                    #elif pkg == 'lxml':
                    #
                    elif pkg == 'pp':
                        exec('import pp; ver = pp.version')
                    elif pkg == 'pynetstation':
                        exec('from psychopy.hardware import egi')
                        ver = 'import ok'
                    elif pkg == 'pyserial':
                        exec('import serial')
                        ver = serial.VERSION
                    elif pkg == 'pywin32':
                        exec('import win32api')
                        ver = 'import ok'
                    else:
                        exec('import ' + pkg)
                        try: ver = eval(pkg+'.__version__')
                        except: ver = 'import ok'
                    report.append((pkg, ver, '', False))
                except (ImportError, AttributeError):
                    report.append((pkg, '&nbsp;&nbsp;--', _translate('could not import package %s') % pkg, False))

        # rewrite to avoid assumption of locale en_US:
        self.warnings = list(set([key for key, val, msg, warn in report if warn]))

        return report
Exemple #14
0
    def runDiagnostics(self, win, verbose=False):
        """Return list of (key, val, msg, warn) tuple, set self.warnings

        All tuple elements will be of <type str>.

        msg can depend on val; warn==True indicates a concern.
        Plain text is returned, expected to be used in html <table>.
        Hyperlinks can be embedded as <a href="...">
        """

        report = []  # add item tuples in display order

        # get lots of info and do quick-to-render visual (want 0 frames drop):
        #     for me, grating draw times are: mean 0.53 ms, SD 0.77 ms
        items = info.RunTimeInfo(win=win,
                                 refreshTest='grating',
                                 verbose=True,
                                 userProcsDetailed=True)

        totalRAM = items['systemMemTotalRAM']
        freeRAM = items['systemMemFreeRAM']
        warn = False
        if freeRAM == 'unknown':
            if totalRAM != 'unknown':
                totalRAM = "%.1fG" % (totalRAM / 1024.0)
            txt = _translate(
                'could not assess available physical RAM; total %s')
            msg = txt % totalRAM
            report.append(('available memory', 'unknown', msg, warn))
        else:
            txt = _translate('physical RAM available for configuration test '
                             '(of %.1fG total)')
            msg = txt % (totalRAM / 1024.)
            if freeRAM < 300:  # in M
                txt = _translate('Warning: low available physical RAM for '
                                 'configuration test (of %.1fG total)')
                msg = txt % (totalRAM / 1024.)
                warn = True
            report.append(('available memory', str(freeRAM) + 'M', msg, warn))

        # ----- PSYCHOPY: -----
        warn = False
        report.append(('PsychoPy', '', '', False))  # not localized
        report.append(
            ('psychopy', __version__,
             _translate('avoid upgrading during an experiment'), False))
        msg = _translate(
            'can be set in <a href="http://www.psychopy.org/general/'
            'prefs.html#application-settings-app">Preferences -> App</a>')
        report.append(('locale', items['systemLocale'], msg, False))
        msg = ''
        v = parse_version
        thisV = v(items['pythonVersion'])
        if (thisV < v('2.7') or (v('3.0') <= thisV < v('3.6'))):
            msg = _translate("Warning: python 2.7 or 3.6 are recommended; "
                             "2.6 and 3.5 might work. Others probably won't.")
            warn = True
        if 'EPD' in items['pythonFullVersion']:
            msg += ' Enthought Python Distribution'
        elif 'PsychoPy3.app' in items['pythonExecutable']:
            msg += ' (PsychoPy StandAlone)'
        bits, linkage = platform.architecture()
        # if not bits.startswith('32'):
        #    msg = 'Warning: 32-bit python required; ' + msg
        report.append(
            ('python version', items['pythonVersion'] + ' &nbsp;(%s)' % bits,
             msg, warn))
        warn = False
        if verbose:
            msg = ''
            if items['pythonWxVersion'] < '2.8.10':
                msg = _translate('Warning: wx 2.8.10 or higher required')
                warn = True
            report.append(('wx', items['pythonWxVersion'], '', warn))
            report.append(
                ('pyglet', items['pythonPygletVersion'][:32], '', False))
            report.append(('rush', str(items['psychopyHaveExtRush']),
                           _translate('for high-priority threads'), False))

        # ----- VISUAL: -----
        report.append(('Visual', '', '', False))
        warn = False
        # openGL settings:
        msg = ''
        if items['openGLVersion'] < '2.':
            msg = _translate(
                'Warning: <a href="http://www.psychopy.org/general/timing'
                '/reducingFrameDrops.html?highlight=OpenGL+2.0">OpenGL '
                '2.0 or higher is ideal</a>.')
            warn = True
        report.append(('openGL version', items['openGLVersion'], msg, warn))
        report.append(('openGL vendor', items['openGLVendor'], '', False))
        report.append(
            ('screen size', ' x '.join(map(str, items['windowSize_pix'])), '',
             False))
        # report.append(('wait blanking', str(items['windowWaitBlanking']), '',
        #   False))

        warn = False
        msg = ''
        if not items['windowHaveShaders']:
            msg = _translate(
                'Warning: <a href="http://www.psychopy.org/general/timing'
                '/reducingFrameDrops.html?highlight=shader">Rendering of'
                ' complex stimuli will be slow</a>.')
            warn = True
        report.append(
            ('have shaders', str(items['windowHaveShaders']), msg, warn))

        warn = False
        msg = _translate(
            'during the drifting <a href="http://www.psychopy.org/api/'
            'visual/gratingstim.html">GratingStim</a>')
        if items['windowRefreshTimeMedian_ms'] < 3.3333333:
            msg = _translate(
                "Warning: too fast? visual sync'ing with the monitor"
                " seems unlikely at 300+ Hz")
            warn = True
        report.append(
            ('visual sync (refresh)',
             "%.2f ms/frame" % items['windowRefreshTimeMedian_ms'], msg, warn))
        msg = _translate('SD &lt; 0.5 ms is ideal (want low variability)')
        warn = False
        if items['windowRefreshTimeSD_ms'] > .5:
            msg = _translate(
                'Warning: the refresh rate has high frame-to-frame '
                'variability (SD &gt; 0.5 ms)')
            warn = True
        report.append(('refresh stability (SD)',
                       "%.2f ms" % items['windowRefreshTimeSD_ms'], msg, warn))

        # draw 100 dots as a minimally demanding visual test:
        # first get baseline frame-rate (safe as possible, no drawing):
        avg, sd, median = visual.getMsPerFrame(win)
        dots100 = visual.DotStim(win,
                                 nDots=100,
                                 speed=0.005,
                                 dotLife=12,
                                 dir=90,
                                 coherence=0.2,
                                 dotSize=8,
                                 fieldShape='circle',
                                 autoLog=False)
        win.recordFrameIntervals = True
        win.frameIntervals = []
        win.flip()
        for i in range(180):
            dots100.draw()
            win.flip()
        msg = _translate('during <a href="http://www.psychopy.org/api/visual/'
                         'dotstim.html">DotStim</a> with 100 random dots')
        warn = False
        intervalsMS = np.array(win.frameIntervals) * 1000
        nTotal = len(intervalsMS)
        nDropped = sum(intervalsMS > (1.5 * median))
        if nDropped:
            msg = _translate(
                'Warning: could not keep up during <a href="http://'
                'www.psychopy.org/api/visual/dotstim.html">DotStim</a>'
                ' with 100 random dots.')
            warn = True
        report.append(
            ('no dropped frames', '%i / %i' % (nDropped, nTotal), msg, warn))
        win.recordFrameIntervals = False

        if verbose:
            report.append(
                ('openGL max vertices',
                 str(items['openGLmaxVerticesInVertexArray']), '', False))
            keyList = ('GL_ARB_multitexture', 'GL_EXT_framebuffer_object',
                       'GL_ARB_fragment_program', 'GL_ARB_shader_objects',
                       'GL_ARB_vertex_shader', 'GL_ARB_texture_float',
                       'GL_ARB_texture_non_power_of_two', 'GL_STEREO')
            for key in keyList:
                val = items['openGLext.' + key]  # boolean
                if not val:
                    val = '<strong>' + str(val) + '</strong>'
                report.append((key, str(val), '', False))

        # ----- AUDIO: -----
        report.append(('Audio', '', '', False))
        msg = ''
        warn = False
        if not 'systemPyoVersion' in items:
            msg = _translate(
                'Warning: pyo is needed for sound and microphone.')
            warn = True
            items['systemPyoVersion'] = _translate('(missing)')
        # elif items['systemPyoVersion'] < '0.6.2':
        #    msg = 'pyo 0.6.2 compiled with --no-messages will
        #    suppress start-up messages'
        report.append(('pyo', items['systemPyoVersion'], msg, warn))
        # TO-DO: add microphone + playback as sound test

        # ----- NUMERIC: -----
        report.append(('Numeric', '', '', False))
        report.append(('numpy', items['pythonNumpyVersion'],
                       _translate('vector-based (fast) calculations'), False))
        report.append(('scipy', items['pythonScipyVersion'],
                       _translate('scientific / numerical'), False))
        report.append(
            ('matplotlib', items['pythonMatplotlibVersion'],
             _translate('plotting; fast contains(), overlaps()'), False))

        # ----- SYSTEM: -----
        report.append(('System', '', '', False))
        report.append(('platform', items['systemPlatform'], '', False))
        msg = _translate('for online help, usage statistics, software '
                         'updates, and google-speech')
        warn = False
        if items['systemHaveInternetAccess'] is not True:
            items['systemHaveInternetAccess'] = 'False'
            msg = _translate('Warning: could not connect (no proxy attempted)')
            warn = True
            # TO-DO: dlg to query whether to try to auto-detect (can take a
            # while), or allow manual entry of proxy str, save into prefs
        val = str(items['systemHaveInternetAccess'])
        report.append(('internet access', val, msg, warn))
        report.append(('auto proxy', str(self.prefs.connections['autoProxy']),
                       _translate('try to auto-detect a proxy if needed; see'
                                  ' <a href="http://www.psychopy.org/general'
                                  '/prefs.html#connection-settings-connection'
                                  's">Preferences -> Connections</a>'), False))
        if not self.prefs.connections['proxy'].strip():
            prx = '&nbsp;&nbsp;--'
        else:
            prx = str(self.prefs.connections['proxy'])
        report.append(('proxy setting', prx,
                       _translate('current manual proxy setting from <a '
                                  'href="http://www.psychopy.org/general/'
                                  'prefs.html#connection-settings-connections'
                                  '">Preferences -> Connections</a>'), False))

        txt = 'CPU speed test'
        report.append(
            (txt, "%.3f s" % items['systemTimeNumpySD1000000_sec'],
             _translate('numpy.std() of 1,000,000 data points'), False))
        # TO-DO: more speed benchmarks
        # - load large image file from disk
        # - transfer image to GPU

        # ----- IMPORTS (relevant for developers & non-StandAlone): -----
        if verbose:  # always False for a real first-run
            report.append((_translate('Python packages'), '', '', False))
            packages = [
                'PIL', 'openpyxl', 'lxml', 'setuptools', 'pytest', 'sphinx',
                'psignifit', 'pyserial', 'pp', 'pynetstation', 'labjack'
            ]
            if sys.platform == 'win32':
                packages.append('pywin32')
                packages.append('winioport')

            if constants.PY3:
                pkgError = ModuleNotFoundError
            else:
                pkgError = ImportError
            for pkg in packages:
                try:
                    if pkg == 'PIL':
                        import PIL
                        ver = PIL.__version__
                    # elif pkg == 'lxml':
                    #
                    elif pkg == 'pynetstation':
                        from psychopy.hardware import egi
                        ver = 'import ok'
                    elif pkg == 'pyserial':
                        import serial
                        ver = serial.VERSION
                    elif pkg == 'pywin32':
                        import win32api
                        ver = 'import ok'
                    else:
                        exec('import ' + pkg)
                        try:
                            ver = eval(pkg + '.__version__')
                        except Exception:
                            ver = 'imported but no version info'
                    report.append((pkg, ver, '', False))
                except (pkgError, AttributeError):
                    msg = _translate('could not import package %s')
                    report.append((pkg, '&nbsp;&nbsp;--', msg % pkg, False))

        # rewrite to avoid assumption of locale en_US:
        self.warnings = list(
            set([key for key, val, msg, warn in report if warn]))

        return report
Exemple #15
0
    def runDiagnostics(self, win, verbose=False):
        """Return list of (key, val, msg, warn) tuple, set self.warnings

        All tuple elements will be of <type str>.

        msg can depend on val; warn==True indicates a concern.
        Plain text is returned, expected to be used in html <table>.
        Hyperlinks can be embedded as <a href="...">
        """

        report = []  # add item tuples in display order

        # get lots of info and do quick-to-render visual (want 0 frames drop):
        #     for me, grating draw times are: mean 0.53 ms, SD 0.77 ms
        items = info.RunTimeInfo(win=win, refreshTest='grating',
                                 verbose=True, userProcsDetailed=True)

        totalRAM = items['systemMemTotalRAM']
        freeRAM = items['systemMemFreeRAM']
        warn = False
        if freeRAM == 'unknown':
            if totalRAM != 'unknown':
                totalRAM = "%.1fG" % (totalRAM/1024.0)
            txt = _translate(
                'could not assess available physical RAM; total %s')
            msg = txt % totalRAM
            report.append(('available memory', 'unknown', msg, warn))
        else:
            txt = _translate(
                'physical RAM available for configuration test '
                '(of %.1fG total)')
            msg = txt % (totalRAM/1024.)
            if freeRAM < 300:  # in M
                txt = _translate(
                    'Warning: low available physical RAM for '
                    'configuration test (of %.1fG total)')
                msg = txt % (totalRAM/1024.)
                warn = True
            report.append(('available memory', str(freeRAM) + 'M',
                           msg, warn))

        # ----- PSYCHOPY: -----
        warn = False
        report.append(('PsychoPy', '', '', False))  # not localized
        report.append(('psychopy', __version__,
                       _translate('avoid upgrading during an experiment'),
                       False))
        msg = _translate(
            'can be set in <a href="http://www.psychopy.org/general/'
            'prefs.html#application-settings-app">Preferences -> App</a>')
        report.append(('locale', items['systemLocale'], msg, False))
        msg = ''
        v = parse_version
        thisV = v(items['pythonVersion'])
        if (thisV < v('2.7') or (v('3.0') <= thisV < v('3.6'))
            ):
            msg = _translate("Warning: python 2.7 or 3.6 are recommended; "
                             "2.6 and 3.5 might work. Others probably won't.")
            warn = True
        if 'EPD' in items['pythonFullVersion']:
            msg += ' Enthought Python Distribution'
        elif 'PsychoPy3.app' in items['pythonExecutable']:
            msg += ' (PsychoPy StandAlone)'
        bits, linkage = platform.architecture()
        # if not bits.startswith('32'):
        #    msg = 'Warning: 32-bit python required; ' + msg
        report.append(
            ('python version',
             items['pythonVersion'] + ' &nbsp;(%s)' % bits,
             msg, warn))
        warn = False
        if verbose:
            msg = ''
            if items['pythonWxVersion'] < '2.8.10':
                msg = _translate('Warning: wx 2.8.10 or higher required')
                warn = True
            report.append(('wx', items['pythonWxVersion'], '', warn))
            report.append(
                ('pyglet', items['pythonPygletVersion'][:32], '', False))
            report.append(('rush', str(items['psychopyHaveExtRush']),
                           _translate('for high-priority threads'), False))

        # ----- VISUAL: -----
        report.append(('Visual', '', '', False))
        warn = False
        # openGL settings:
        msg = ''
        if items['openGLVersion'] < '2.':
            msg = _translate(
                'Warning: <a href="http://www.psychopy.org/general/timing'
                '/reducingFrameDrops.html?highlight=OpenGL+2.0">OpenGL '
                '2.0 or higher is ideal</a>.')
            warn = True
        report.append(('openGL version', items['openGLVersion'], msg, warn))
        report.append(('openGL vendor', items['openGLVendor'], '', False))
        report.append(('screen size', ' x '.join(
            map(str, items['windowSize_pix'])), '', False))
        # report.append(('wait blanking', str(items['windowWaitBlanking']), '',
        #   False))

        warn = False
        msg = ''
        if not items['windowHaveShaders']:
            msg = _translate(
                'Warning: <a href="http://www.psychopy.org/general/timing'
                '/reducingFrameDrops.html?highlight=shader">Rendering of'
                ' complex stimuli will be slow</a>.')
            warn = True
        report.append(('have shaders', str(
            items['windowHaveShaders']), msg, warn))

        warn = False
        msg = _translate(
            'during the drifting <a href="http://www.psychopy.org/api/'
            'visual/gratingstim.html">GratingStim</a>')
        if items['windowRefreshTimeMedian_ms'] < 3.3333333:
            msg = _translate(
                "Warning: too fast? visual sync'ing with the monitor"
                " seems unlikely at 300+ Hz")
            warn = True
        report.append(('visual sync (refresh)', "%.2f ms/frame" %
                       items['windowRefreshTimeMedian_ms'], msg, warn))
        msg = _translate('SD &lt; 0.5 ms is ideal (want low variability)')
        warn = False
        if items['windowRefreshTimeSD_ms'] > .5:
            msg = _translate(
                'Warning: the refresh rate has high frame-to-frame '
                'variability (SD &gt; 0.5 ms)')
            warn = True
        report.append(('refresh stability (SD)', "%.2f ms" %
                       items['windowRefreshTimeSD_ms'], msg, warn))

        # draw 100 dots as a minimally demanding visual test:
        # first get baseline frame-rate (safe as possible, no drawing):
        avg, sd, median = visual.getMsPerFrame(win)
        dots100 = visual.DotStim(
            win, nDots=100, speed=0.005, dotLife=12, dir=90,
            coherence=0.2, dotSize=8, fieldShape='circle', autoLog=False)
        win.recordFrameIntervals = True
        win.frameIntervals = []
        win.flip()
        for i in range(180):
            dots100.draw()
            win.flip()
        msg = _translate(
            'during <a href="http://www.psychopy.org/api/visual/'
            'dotstim.html">DotStim</a> with 100 random dots')
        warn = False
        intervalsMS = np.array(win.frameIntervals) * 1000
        nTotal = len(intervalsMS)
        nDropped = sum(intervalsMS > (1.5 * median))
        if nDropped:
            msg = _translate(
                'Warning: could not keep up during <a href="http://'
                'www.psychopy.org/api/visual/dotstim.html">DotStim</a>'
                ' with 100 random dots.')
            warn = True
        report.append(('no dropped frames', '%i / %i' % (nDropped, nTotal),
                       msg, warn))
        win.recordFrameIntervals = False

        if verbose:
            report.append(('openGL max vertices',
                           str(items['openGLmaxVerticesInVertexArray']),
                           '', False))
            keyList = ('GL_ARB_multitexture', 'GL_EXT_framebuffer_object',
                       'GL_ARB_fragment_program', 'GL_ARB_shader_objects',
                       'GL_ARB_vertex_shader', 'GL_ARB_texture_float',
                       'GL_ARB_texture_non_power_of_two', 'GL_STEREO')
            for key in keyList:
                val = items['openGLext.' + key]  # boolean
                if not val:
                    val = '<strong>' + str(val) + '</strong>'
                report.append((key, str(val), '', False))

        # ----- AUDIO: -----
        report.append(('Audio', '', '', False))
        msg = ''
        warn = False
        if not 'systemPyoVersion' in items:
            msg = _translate(
                'Warning: pyo is needed for sound and microphone.')
            warn = True
            items['systemPyoVersion'] = _translate('(missing)')
        # elif items['systemPyoVersion'] < '0.6.2':
        #    msg = 'pyo 0.6.2 compiled with --no-messages will
        #    suppress start-up messages'
        report.append(('pyo', items['systemPyoVersion'], msg, warn))
        # TO-DO: add microphone + playback as sound test

        # ----- NUMERIC: -----
        report.append(('Numeric', '', '', False))
        report.append(('numpy', items['pythonNumpyVersion'],
                       _translate('vector-based (fast) calculations'), False))
        report.append(('scipy', items['pythonScipyVersion'],
                       _translate('scientific / numerical'), False))
        report.append(('matplotlib', items['pythonMatplotlibVersion'],
                       _translate('plotting; fast contains(), overlaps()'),
                       False))

        # ----- SYSTEM: -----
        report.append(('System', '', '', False))
        report.append(('platform', items['systemPlatform'], '', False))
        msg = _translate('for online help, usage statistics, software '
                         'updates, and google-speech')
        warn = False
        if items['systemHaveInternetAccess'] is not True:
            items['systemHaveInternetAccess'] = 'False'
            msg = _translate('Warning: could not connect (no proxy attempted)')
            warn = True
            # TO-DO: dlg to query whether to try to auto-detect (can take a
            # while), or allow manual entry of proxy str, save into prefs
        val = str(items['systemHaveInternetAccess'])
        report.append(('internet access', val, msg, warn))
        report.append(('auto proxy',
                       str(self.prefs.connections['autoProxy']),
                       _translate('try to auto-detect a proxy if needed; see'
                                  ' <a href="http://www.psychopy.org/general'
                                  '/prefs.html#connection-settings-connection'
                                  's">Preferences -> Connections</a>'),
                       False))
        if not self.prefs.connections['proxy'].strip():
            prx = '&nbsp;&nbsp;--'
        else:
            prx = str(self.prefs.connections['proxy'])
        report.append(('proxy setting', prx,
                       _translate('current manual proxy setting from <a '
                                  'href="http://www.psychopy.org/general/'
                                  'prefs.html#connection-settings-connections'
                                  '">Preferences -> Connections</a>'), False))

        txt = 'CPU speed test'
        report.append((txt, "%.3f s" % items['systemTimeNumpySD1000000_sec'],
                       _translate('numpy.std() of 1,000,000 data points'),
                       False))
        # TO-DO: more speed benchmarks
        # - load large image file from disk
        # - transfer image to GPU

        # ----- IMPORTS (relevant for developers & non-StandAlone): -----
        if verbose:  # always False for a real first-run
            report.append((_translate('Python packages'), '', '', False))
            packages = ['PIL', 'openpyxl', 'lxml', 'setuptools', 'pytest',
                        'sphinx', 'psignifit', 'pyserial', 'pp',
                        'pynetstation', 'labjack']
            if sys.platform == 'win32':
                packages.append('pywin32')
                packages.append('winioport')

            if constants.PY3:
                pkgError = ModuleNotFoundError
            else:
                pkgError = ImportError
            for pkg in packages:
                try:
                    if pkg == 'PIL':
                        import PIL
                        ver = PIL.__version__
                    # elif pkg == 'lxml':
                    #
                    elif pkg == 'pynetstation':
                        from psychopy.hardware import egi
                        ver = 'import ok'
                    elif pkg == 'pyserial':
                        import serial
                        ver = serial.VERSION
                    elif pkg == 'pywin32':
                        import win32api
                        ver = 'import ok'
                    else:
                        exec('import ' + pkg)
                        try:
                            ver = eval(pkg + '.__version__')
                        except Exception:
                            ver = 'imported but no version info'
                    report.append((pkg, ver, '', False))
                except (pkgError, AttributeError):
                    msg = _translate('could not import package %s')
                    report.append((pkg, '&nbsp;&nbsp;--', msg % pkg, False))

        # rewrite to avoid assumption of locale en_US:
        self.warnings = list(
            set([key for key, val, msg, warn in report if warn]))

        return report
Exemple #16
0
    def runDiagnostics(self, win, verbose=False):
        """Return list of (key, val, msg, warn) tuple, set self.warnings

        All tuple elements will be of <type str>.

        msg can depend on val; warn==True indicates a concern.
        Plain text is returned, expected to be used in html <table>.
        Hyperlinks can be embedded as <a href="...">
        """

        report = []  # add item tuples in display order

        # get lots of info and do quick-to-render visual (want no frames drop):
        #     for me, grating draw times are: mean 0.53 ms, SD 0.77 ms
        items = info.RunTimeInfo(win=win, refreshTest="grating", verbose=True, userProcsDetailed=True)

        totalRAM, freeRAM = items["systemMemTotalRAM"], items["systemMemFreeRAM"]
        warn = False
        if freeRAM == "unknown":
            if totalRAM != "unknown":
                totalRAM = "%.1fG" % (totalRAM / 1024.0)
            msg = _translate("could not assess available physical RAM; total %s") % totalRAM
            report.append(("available memory", "unknown", msg, warn))
        else:
            msg = _translate("physical RAM available for configuration test (of %.1fG total)") % (totalRAM / 1024.0)
            if freeRAM < 300:  # in M
                msg = _translate("Warning: low available physical RAM for configuration test (of %.1fG total)") % (
                    totalRAM / 1024.0
                )
                warn = True
            report.append(("available memory", unicode(freeRAM) + "M", msg, warn))

        # ----- PSYCHOPY: -----
        warn = False
        report.append(("PsychoPy", "", "", False))  # not localized
        report.append(("psychopy", __version__, _translate("avoid upgrading during an experiment"), False))
        report.append(
            (
                "locale",
                items["systemLocale"],
                _translate(
                    'can be set in <a href="http://www.psychopy.org/general/prefs.html#application-settings">Preferences -> App</a>'
                ),
                False,
            )
        )
        msg = ""
        if items["pythonVersion"] < "2.5" or items["pythonVersion"] >= "3":
            msg = _translate("Warning: python 2.6 or 2.7 required; 2.5 is not supported but might work")
            warn = True
        if "EPD" in items["pythonFullVersion"]:
            msg += " Enthought Python Distribution"
        elif "PsychoPy2.app" in items["pythonExecutable"]:
            msg += " (PsychoPy StandAlone)"
        bits, linkage = platform.architecture()
        # if not bits.startswith('32'):
        #    msg = 'Warning: 32-bit python required; ' + msg
        report.append(("python version", items["pythonVersion"] + " &nbsp;(%s)" % bits, msg, warn))
        warn = False
        if verbose:
            msg = ""
            if items["pythonWxVersion"] < "2.8.10":
                msg = _translate("Warning: wx 2.8.10 or higher required")
                warn = True
            report.append(("wx", items["pythonWxVersion"], "", warn))
            report.append(("pyglet", items["pythonPygletVersion"][:32], "", False))
            report.append(("rush", str(items["psychopyHaveExtRush"]), _translate("for high-priority threads"), False))

        # ----- VISUAL: -----
        report.append(("Visual", "", "", False))
        warn = False
        # openGL settings:
        msg = ""
        if items["openGLVersion"] < "2.":
            msg = _translate(
                'Warning: <a href="http://www.psychopy.org/general/timing/reducingFrameDrops.html?highlight=OpenGL+2.0">OpenGL 2.0 or higher is ideal</a>.'
            )
            warn = True
        report.append(("openGL version", items["openGLVersion"], msg, warn))
        report.append(("openGL vendor", items["openGLVendor"], "", False))
        report.append(("screen size", " x ".join(map(str, items["windowSize_pix"])), "", False))
        # report.append(('wait blanking', str(items['windowWaitBlanking']), '', False))

        warn = False
        msg = ""
        if not items["windowHaveShaders"]:
            msg = _translate(
                'Warning: <a href="http://www.psychopy.org/general/timing/reducingFrameDrops.html?highlight=shader">Rendering of complex stimuli will be slow</a>.'
            )
            warn = True
        report.append(("have shaders", str(items["windowHaveShaders"]), msg, warn))

        warn = False
        msg = _translate(
            'during the drifting <a href="http://www.psychopy.org/api/visual/gratingstim.html">GratingStim</a>'
        )
        if items["windowRefreshTimeMedian_ms"] < 3.3333333:
            msg = _translate("""Warning: too fast? visual sync'ing with the monitor seems unlikely at 300+ Hz""")
            warn = True
        report.append(("visual sync (refresh)", "%.2f ms/frame" % items["windowRefreshTimeMedian_ms"], msg, warn))
        msg = _translate("SD < 0.5 ms is ideal (want low variability)")
        warn = False
        if items["windowRefreshTimeSD_ms"] > 0.5:
            msg = _translate("Warning: the refresh rate has high frame-to-frame variability (SD > 0.5 ms)")
            warn = True
        report.append(("refresh stability (SD)", "%.2f ms" % items["windowRefreshTimeSD_ms"], msg, warn))

        # draw 100 dots as a minimally demanding visual test:
        # first get baseline frame-rate (safe as possible, no drawing):
        avg, sd, median = visual.getMsPerFrame(win)
        dots100 = visual.DotStim(
            win,
            nDots=100,
            speed=0.005,
            dotLife=12,
            dir=90,
            coherence=0.2,
            dotSize=8,
            fieldShape="circle",
            autoLog=False,
        )
        win.recordFrameIntervals = True
        win.frameIntervals = []
        win.flip()
        for i in xrange(180):
            dots100.draw()
            win.flip()
        msg = _translate(
            'during <a href="http://www.psychopy.org/api/visual/dotstim.html">DotStim</a> with 100 random dots'
        )
        warn = False
        intervalsMS = np.array(win.frameIntervals) * 1000
        nTotal = len(intervalsMS)
        nDropped = sum(intervalsMS > (1.5 * median))
        if nDropped:
            msg = _translate(
                'Warning: could not keep up during <a href="http://www.psychopy.org/api/visual/dotstim.html">DotStim</a> with 100 random dots.'
            )
            warn = True
        report.append(("no dropped frames", "%i / %i" % (nDropped, nTotal), msg, warn))
        win.recordFrameIntervals = False

        msg = _translate("for movies")
        warn = False
        try:
            from pyglet.media import avbin
        except:  # not sure what error to catch, WindowsError not found
            report.append(
                (
                    "pyglet avbin",
                    "import error",
                    _translate("Warning: could not import avbin; playing movies will not work"),
                    True,
                )
            )
        else:
            ver = avbin.get_version()
            if sys.platform.startswith("linux"):
                if not (7 <= ver < 8):
                    msg = _translate("Warning: version 7 recommended on linux (for movies)")
                    warn = True
            elif not (5 <= ver < 6):
                msg = _translate(
                    'Warning: version 5 recommended (for movies); Visit <a href="http://code.google.com/p/avbin">download page</a> [google.com]'
                )
                warn = True
            report.append(("pyglet avbin", unicode(ver), msg, warn))

        if verbose:
            report.append(("openGL max vertices", str(items["openGLmaxVerticesInVertexArray"]), "", False))
            keyList = [
                "GL_ARB_multitexture",
                "GL_EXT_framebuffer_object",
                "GL_ARB_fragment_program",
                "GL_ARB_shader_objects",
                "GL_ARB_vertex_shader",
                "GL_ARB_texture_non_power_of_two",
                "GL_ARB_texture_float",
                "GL_STEREO",
            ]
            for key in keyList:
                val = items["openGLext." + key]  # boolean
                if not val:
                    val = "<strong>" + str(val) + "</strong>"
                report.append((key, str(val), "", False))

        # ----- AUDIO: -----
        report.append(("Audio", "", "", False))
        msg = ""
        warn = False
        if not "systemPyoVersion" in items:
            msg = _translate("Warning: pyo is needed for sound and microphone.")
            warn = True
            items["systemPyoVersion"] = _translate("(missing)")
        # elif items['systemPyoVersion'] < '0.6.2':
        #    msg = 'pyo 0.6.2 compiled with --no-messages will suppress start-up messages'
        report.append(("pyo", items["systemPyoVersion"], msg, warn))
        # sound latencies from portaudio; requires pyo svn r1024
        try:
            sndInputDevices = items["systemPyo.InputDevices"]
            warn = False
            if len(sndInputDevices.keys()):
                key = sndInputDevices.keys()[0]
                mic = sndInputDevices[key]
                if mic["name"].endswith("icroph"):
                    mic["name"] += "one"  # portaudio (?) seems to clip to 16 chars
                msg = '"%s"' % mic["name"]
                if mic["latency"] > 0.01:
                    msg = _translate('Warning: "%s" latency > 10ms') % mic["name"]
                    warn = True
                report.append(("microphone latency", "%.4f s" % mic["latency"], msg, warn))
            else:
                report.append(("microphone", _translate("(not detected)"), "", False))
            sndOutputDevices = items["systemPyo.OutputDevices"]
            if len(sndOutputDevices.keys()):
                warn = False
                key = sndOutputDevices.keys()[0]
                spkr = sndOutputDevices[key]
                msg = '"%s"' % spkr["name"]
                if spkr["latency"] > 0.01:
                    msg = _translate('Warning: "%s" latency > 10ms') % spkr["name"]
                    warn = True
                report.append(("speakers latency", "%.4f s" % spkr["latency"], msg, warn))
            else:
                report.append(("speakers", _translate("(not detected)"), "", False))
        except KeyError:
            pass
        s2t = '<a href="http://www.psychopy.org/api/microphone.html?highlight=Speech2Text">speech-to-text</a>'
        msg = _translate("audio codec for %s and sound file compression") % s2t
        warn = False
        if not "systemFlacVersion" in items:
            msg = (
                _translate("Warning: flac is needed for using %s and sound compression.") % s2t
                + ' <a href="http://flac.sourceforge.net/download.html">'
                + _translate("Download</a> [sourceforge.net].")
            )
            warn = True
            items["systemFlacVersion"] = _translate("(missing)")
        if verbose:
            report.append(("flac", items["systemFlacVersion"].lstrip("flac "), msg, warn))
        # TO-DO: add microphone + playback as sound test

        # ----- NUMERIC: -----
        report.append(("Numeric", "", "", False))
        report.append(("numpy", items["pythonNumpyVersion"], _translate("vector-based (fast) calculations"), False))
        report.append(("scipy", items["pythonScipyVersion"], _translate("scientific / numerical"), False))
        report.append(
            ("matplotlib", items["pythonMatplotlibVersion"], _translate("plotting; fast contains(), overlaps()"), False)
        )

        # ----- SYSTEM: -----
        report.append(("System", "", "", False))
        report.append(("platform", items["systemPlatform"], "", False))
        msg = _translate("for online help, usage statistics, software updates, and google-speech")
        warn = False
        if items["systemHaveInternetAccess"] is not True:
            items["systemHaveInternetAccess"] = "False"
            msg = _translate("Warning: could not connect (no proxy attempted)")
            warn = True
            # TO-DO: dlg to query whether to try to auto-detect (can take a while), or allow manual entry of proxy str, save into prefs
        val = str(items["systemHaveInternetAccess"])
        report.append(("internet access", val, msg, warn))
        report.append(
            (
                "auto proxy",
                str(self.prefs.connections["autoProxy"]),
                _translate(
                    'try to auto-detect a proxy if needed; see <a href="http://www.psychopy.org/general/prefs.html#connection-settings">Preferences -> Connections</a>'
                ),
                False,
            )
        )
        if not self.prefs.connections["proxy"].strip():
            prx = "&nbsp;&nbsp--"
        else:
            prx = unicode(self.prefs.connections["proxy"])
        report.append(
            (
                "proxy setting",
                prx,
                _translate(
                    'current manual proxy setting from <a href="http://www.psychopy.org/general/prefs.html#connection-settings">Preferences -> Connections</a>'
                ),
                False,
            )
        )

        msg = ""
        warn = False
        # assure that we have a list
        if items["systemUserProcFlagged"] is None:
            items["systemUserProcFlagged"] = []
        items["systemUserProcFlagged"].sort()
        self.badBgProc = [p for p, pid in items["systemUserProcFlagged"]]
        if len(self.badBgProc):
            val = "%s ..." % self.badBgProc[0]
            msg = _translate(
                'Warning: Some <a href="http://www.psychopy.org/general/timing/reducingFrameDrops.html?highlight=background+processes">background processes</a> can adversely affect timing'
            )
            warn = True
        else:
            val = _translate("No bad background processes active.")
        report.append(("background processes", val, msg, warn))
        if verbose and "systemSec.OpenSSLVersion" in items:
            report.append(
                (
                    "OpenSSL",
                    items["systemSec.OpenSSLVersion"].lstrip("OpenSSL "),
                    'for <a href="http://www.psychopy.org/api/encryption.html">encryption</a>',
                    False,
                )
            )
        report.append(
            (
                "CPU speed test",
                "%.3f s" % items["systemTimeNumpySD1000000_sec"],
                _translate("numpy.std() of 1,000,000 data points"),
                False,
            )
        )
        # TO-DO: more speed benchmarks
        # - load large image file from disk
        # - transfer image to GPU

        # ----- IMPORTS (relevant for developers & non-StandAlone): -----
        if verbose:  # always False for a real first-run
            report.append((_translate("Python packages"), "", "", False))
            packages = [
                "PIL",
                "openpyxl",
                "lxml",
                "setuptools",
                "pytest",
                "sphinx",
                "psignifit",
                "pyserial",
                "pp",
                "pynetstation",
                "ioLabs",
                "labjack",
            ]
            if sys.platform == "win32":
                packages.append("pywin32")
                packages.append("winioport")
            for pkg in packages:
                try:
                    if pkg == "PIL":
                        exec ("import PIL.Image")
                        ver = PIL.Image.VERSION
                    # elif pkg == 'lxml':
                    #
                    elif pkg == "pp":
                        exec ("import pp; ver = pp.version")
                    elif pkg == "pynetstation":
                        exec ("from psychopy.hardware import egi")
                        ver = "import ok"
                    elif pkg == "pyserial":
                        exec ("import serial")
                        ver = serial.VERSION
                    elif pkg == "pywin32":
                        exec ("import win32api")
                        ver = "import ok"
                    else:
                        exec ("import " + pkg)
                        try:
                            ver = eval(pkg + ".__version__")
                        except:
                            ver = "import ok"
                    report.append((pkg, ver, "", False))
                except (ImportError, AttributeError):
                    report.append((pkg, "&nbsp;&nbsp--", _translate("could not import package %s") % pkg, False))

        # rewrite to avoid assumption of locale en_US:
        self.warnings = list(set([key for key, val, msg, warn in report if warn]))

        return report
Exemple #17
0
    def __init__(self, fixation_duration, max_dot_duration, min_iti_duration, break_duration):
        '''
        RDMD task
        hemifield = hemifield to show dot stim in (right or left)
        fixation_duration = duration of fixation (ms)
        max_dot_duration = max duration of dot stimuli (ms)
        min_iti_duration = min inter-trial-interval (ms)
        break_duration = duration of break (ms)
        '''
        #create window and stimuli
        # Window to use
        self.wintype='pyglet' # use pyglet if possible, it's faster at event handling
        self.win = visual.Window(
            [1280,1024],
            monitor=MONITOR,
            screen=SCREEN,
            units="deg",
            fullscr=True,
            color=[-1,-1,-1],
            winType=self.wintype)
        self.win.setMouseVisible(False)
        event.clearEvents()

        # Measure frame rate
        self.mean_ms_per_frame, std_ms_per_frame, median_ms_per_frame=visual.getMsPerFrame(self.win, nFrames=60,
            showVisual=True)

        # Compute number of frames for fixation
        self.fixation_duration=fixation_duration
        self.fixation_frames=int(fixation_duration/self.mean_ms_per_frame)

        # Compute max number of frames for dot stimuli
        self.max_dot_duration=max_dot_duration
        self.max_dot_frames=int(max_dot_duration/self.mean_ms_per_frame)

        # Compute minimum inter-trial-interval frames (will be adjusted based on time of other stimuli)
        self.min_iti_duration=min_iti_duration
        self.min_iti_frames=int(min_iti_duration/self.mean_ms_per_frame)

        self.break_duration=break_duration
        self.break_duration_frames=int(break_duration/self.mean_ms_per_frame)

        # fixation stimulus
        self.fixation = visual.PatchStim(
            self.win,
            units='deg',
            tex=None,
            mask='circle',
            sf=0,
            size=0.5,
            name='fixation',
            autoLog=False,
            color=[1,1,1]
        )

        # dot stimulus
        self.dots = visual.DotStim(
            win=self.win,
            name='dots',
            nDots=200, # number of dots
            dotSize=2, # dot size in degrees
            speed=0.4, # 60Hz refresh - 16.7ms/frame, 4deg/s=.0668deg/frame
            dir=0.0, # 0=right, 180=left
            coherence=12.5, # percentage of dots moving in the same direction
            fieldPos=[0.0, 0.0], # centered on the screen
            fieldSize=10.0, # field is 10 deg wide
            fieldShape='circle', # circle shaped field
            signalDots='different', # are the signal and noise dots 'different' or 'same' popns (see Scase et al)
            noiseDots='direction', # do the noise dots follow random- 'walk', 'direction', or 'position'
            dotLife=3, # number of frames for each dot to be drawn
            color=[1.0,1.0,1.0], # white dots
            colorSpace='rgb',
            opacity=1, # fully opaque
            depth=-1.0
        )

        self.training_message = visual.TextStim(self.win, wrapWidth=30, pos=[0,3])

        # Clock for computing response time
        self.rt_clock = core.Clock()