Ejemplo n.º 1
0
    def writeWindowCode(self, buff):
        """Setup the window code.
        """
        buff.writeIndentedLines("\n# Setup the Window\n")
        # get parameters for the Window
        fullScr = self.params['Full-screen window'].val
        # if fullscreen then hide the mouse, unless its requested explicitly
        allowGUI = (not bool(fullScr)) or bool(self.params['Show mouse'].val)
        allowStencil = False
        # NB routines is a dict:
        for thisRoutine in list(self.exp.routines.values()):
            # a single routine is a list of components:
            for thisComp in thisRoutine:
                if thisComp.type == 'Aperture':
                    allowStencil = True
                if thisComp.type == 'RatingScale':
                    allowGUI = True  # to have a mouse

        requestedScreenNumber = int(self.params['Screen'].val)
        nScreens = 10
        # try:
        #     nScreens = wx.Display.GetCount()
        # except Exception:
        #     # will fail if application hasn't been created (e.g. in test
        #     # environments)
        #     nScreens = 10
        if requestedScreenNumber > nScreens:
            logging.warn("Requested screen can't be found. Writing script "
                         "using first available screen.")
            screenNumber = 0
        else:
            # computer has 1 as first screen
            screenNumber = requestedScreenNumber - 1

        size = self.params['Window size (pixels)']
        code = ("win = visual.Window(\n    size=%s, fullscr=%s, screen=%s,"
                "\n    allowGUI=%s, allowStencil=%s,\n")
        vals = (size, fullScr, screenNumber, allowGUI, allowStencil)
        buff.writeIndented(code % vals)
        code = ("    monitor=%(Monitor)s, color=%(color)s, "
                "colorSpace=%(colorSpace)s,\n")
        if self.params['blendMode'].val:
            code += "    blendMode=%(blendMode)s, useFBO=True,\n"

        if self.params['Units'].val != 'use prefs':
            code += "    units=%(Units)s"
        code = code.rstrip(', \n') + ')\n'
        buff.writeIndentedLines(code % self.params)

        if 'microphone' in self.exp.psychopyLibs:  # need a pyo Server
            buff.writeIndentedLines("\n# Enable sound input/output:\n"
                                    "microphone.switchOn()\n")

        code = ("# store frame rate of monitor if we can measure it\n"
                "expInfo['frameRate'] = win.getActualFrameRate()\n"
                "if expInfo['frameRate'] != None:\n"
                "    frameDur = 1.0 / round(expInfo['frameRate'])\n"
                "else:\n"
                "    frameDur = 1.0 / 60.0  # could not measure, so guess\n")
        buff.writeIndentedLines(code)
Ejemplo n.º 2
0
    def setMouseType(self, name='arrow'):
        """Change the appearance of the cursor for this window. Cursor types
        provide contextual hints about how to interact with on-screen objects.

        The graphics used 'standard cursors' provided by the operating system.
        They may vary in appearance and hot spot location across platforms. The
        following names are valid on most platforms:

                'arrow' : Default pointer
                'ibeam' : Indicates text can be edited
            'crosshair' : Crosshair with hot-spot at center
                 'hand' : A pointing hand
              'hresize' : Double arrows pointing horizontally
              'vresize' : Double arrows pointing vertically

        Note, on Windows the 'crosshair' option is XORed with the background
        color. It will not be visible when placed over 50% grey fields.

        :param name: str, type of standard cursor to use
        :return:

        """
        try:
            glfw.set_cursor(self.winHandle, _CURSORS_[name])
        except KeyError:
            logging.warn(
                "Invalid cursor type name '{}', using default.".format(type))
            glfw.set_cursor(self.winHandle, _CURSORS_['arrow'])
Ejemplo n.º 3
0
def flac2wav(path, keep=True):
    """Uncompress: convert .flac file (on disk) to .wav format (new file).

    If `path` is a directory name, convert all .flac files in the directory.

    `keep` to retain the original .flac file(s), default `True`.
    """
    flac_path = _getFlacPath()
    flac_files = []
    if path.endswith('.flac'):
        flac_files = [path]
    elif type(path) == str and os.path.isdir(path):
        flac_files = glob.glob(os.path.join(path, '*.flac'))
    if len(flac_files) == 0:
        logging.warn('failed to find .flac file(s) from %s' % path)
        return None
    wav_files = []
    for flacfile in flac_files:
        wavname = flacfile.strip('.flac') + '.wav'
        flac_cmd = [
            flac_path, "-d", "--totally-silent", "-f", "-o", wavname, flacfile
        ]
        _junk, se = core.shellCall(flac_cmd, stderr=True)
        if se:
            logging.error(se)
        if not keep:
            os.unlink(flacfile)
        wav_files.append(wavname)
    if len(wav_files) == 1:
        return wav_files[0]
    else:
        return wav_files
Ejemplo n.º 4
0
    def resample(self, newRate=16000, keep=True):
        """Re-sample the saved file to a new rate, return the full path.
        
        Can take several visual frames to resample a 2s recording.
        
        The default values for resample() are for google-speech, keeping the
        original (presumably recorded at 48kHz) to archive.
        A warning is generated if the new rate not an integer factor / multiple of the old rate.
        
        To control anti-aliasing, use pyo.downsamp() or upsamp() directly.
        """
        if not self.savedFile or not os.path.isfile(self.savedFile):
            msg = '%s: Re-sample requested but no saved file' % self.loggingId
            logging.error(msg)
            raise ValueError(msg)
        if newRate <= 0 or type(newRate) != int:
            msg = '%s: Re-sample bad new rate = %s' % (self.loggingId,
                                                       repr(newRate))
            logging.error(msg)
            raise ValueError(msg)

        # set-up:
        if self.rate >= newRate:
            ratio = float(self.rate) / newRate
            info = '-ds%i' % ratio
        else:
            ratio = float(newRate) / self.rate
            info = '-us%i' % ratio
        if ratio != int(ratio):
            logging.warn('%s: old rate is not an integer factor of new rate' %
                         self.loggingId)
        ratio = int(ratio)
        newFile = info.join(os.path.splitext(self.savedFile))

        # use pyo's downsamp or upsamp based on relative rates:
        if not ratio:
            logging.warn('%s: Re-sample by %sx is undefined, skipping' %
                         (self.loggingId, str(ratio)))
        elif self.rate >= newRate:
            t0 = time.time()
            downsamp(self.savedFile, newFile,
                     ratio)  # default 128-sample anti-aliasing
            logging.exp(
                '%s: Down-sampled %sx in %.3fs to %s' %
                (self.loggingId, str(ratio), time.time() - t0, newFile))
        else:
            t0 = time.time()
            upsamp(self.savedFile, newFile,
                   ratio)  # default 128-sample anti-aliasing
            logging.exp(
                '%s: Up-sampled %sx in %.3fs to %s' %
                (self.loggingId, str(ratio), time.time() - t0, newFile))

        # clean-up:
        if not keep:
            os.unlink(self.savedFile)
            self.savedFile = newFile
            self.rate = newRate

        return os.path.abspath(newFile)
Ejemplo n.º 5
0
    def setMouseType(self, name='arrow'):
        """Change the appearance of the cursor for this window. Cursor types
        provide contextual hints about how to interact with on-screen objects.

        The graphics used 'standard cursors' provided by the operating system.
        They may vary in appearance and hot spot location across platforms. The
        following names are valid on most platforms:

        * ``arrow`` : Default pointer
        * ``ibeam`` : Indicates text can be edited
        * ``crosshair`` : Crosshair with hot-spot at center
        * ``hand`` : A pointing hand
        * ``hresize`` : Double arrows pointing horizontally
        * ``vresize`` : Double arrows pointing vertically

        Requires the GLFW backend, otherwise this function does nothing! Note,
        on Windows the ``crosshair`` option is negated with the background
        color. It will not be visible when placed over 50% grey fields.

        Parameters
        ----------
        name : str
            Type of standard cursor to use.

        """
        try:
            glfw.set_cursor(self.winHandle, _CURSORS_[name])
        except KeyError:
            logging.warn(
                "Invalid cursor type name '{}', using default.".format(type))
            glfw.set_cursor(self.winHandle, _CURSORS_['arrow'])
Ejemplo n.º 6
0
    def setMouseType(self, name='arrow'):
        """Change the appearance of the cursor for this window. Cursor types
        provide contextual hints about how to interact with on-screen objects.

        The graphics used 'standard cursors' provided by the operating system.
        They may vary in appearance and hot spot location across platforms. The
        following names are valid on most platforms:

        * ``arrow`` : Default pointer
        * ``ibeam`` : Indicates text can be edited
        * ``crosshair`` : Crosshair with hot-spot at center
        * ``hand`` : A pointing hand
        * ``hresize`` : Double arrows pointing horizontally
        * ``vresize`` : Double arrows pointing vertically

        Requires the GLFW backend, otherwise this function does nothing! Note,
        on Windows the ``crosshair`` option is negated with the background
        color. It will not be visible when placed over 50% grey fields.

        Parameters
        ----------
        name : str
            Type of standard cursor to use.

        """
        try:
            glfw.set_cursor(self.winHandle, _CURSORS_[name])
        except KeyError:
            logging.warn(
                "Invalid cursor type name '{}', using default.".format(type))
            glfw.set_cursor(self.winHandle, _CURSORS_['arrow'])
Ejemplo n.º 7
0
    def writeWindowCode(self, buff):
        """Setup the window code.
        """
        buff.writeIndentedLines("\n# Setup the Window\n")
        # get parameters for the Window
        fullScr = self.params['Full-screen window'].val
        # if fullscreen then hide the mouse, unless its requested explicitly
        allowGUI = (not bool(fullScr)) or bool(self.params['Show mouse'].val)
        allowStencil = False
        # NB routines is a dict:
        for thisRoutine in list(self.exp.routines.values()):
            # a single routine is a list of components:
            for thisComp in thisRoutine:
                if thisComp.type == 'Aperture':
                    allowStencil = True
                if thisComp.type == 'RatingScale':
                    allowGUI = True  # to have a mouse

        requestedScreenNumber = int(self.params['Screen'].val)
        nScreens = 10
        # try:
        #     nScreens = wx.Display.GetCount()
        # except Exception:
        #     # will fail if application hasn't been created (e.g. in test
        #     # environments)
        #     nScreens = 10
        if requestedScreenNumber > nScreens:
            logging.warn("Requested screen can't be found. Writing script "
                         "using first available screen.")
            screenNumber = 0
        else:
            # computer has 1 as first screen
            screenNumber = requestedScreenNumber - 1

        size = self.params['Window size (pixels)']
        code = ("win = visual.Window(\n    size=%s, fullscr=%s, screen=%s,"
                "\n    allowGUI=%s, allowStencil=%s,\n")
        vals = (size, fullScr, screenNumber, allowGUI, allowStencil)
        buff.writeIndented(code % vals)
        code = ("    monitor=%(Monitor)s, color=%(color)s, "
                "colorSpace=%(colorSpace)s,\n")
        if self.params['blendMode'].val:
            code += "    blendMode=%(blendMode)s, useFBO=True,\n"

        if self.params['Units'].val != 'use prefs':
            code += "    units=%(Units)s"
        code = code.rstrip(', \n') + ')\n'
        buff.writeIndentedLines(code % self.params)

        if 'microphone' in self.exp.psychopyLibs:  # need a pyo Server
            buff.writeIndentedLines("\n# Enable sound input/output:\n"
                                    "microphone.switchOn()\n")

        code = ("# store frame rate of monitor if we can measure it\n"
                "expInfo['frameRate'] = win.getActualFrameRate()\n"
                "if expInfo['frameRate'] != None:\n"
                "    frameDur = 1.0 / round(expInfo['frameRate'])\n"
                "else:\n"
                "    frameDur = 1.0 / 60.0  # could not measure, so guess\n")
        buff.writeIndentedLines(code)
Ejemplo n.º 8
0
def setGammaRamp(pygletWindow, newRamp, nAttempts=3):
    """Sets the hardware look-up table, using platform-specific ctypes functions.
    For use with pyglet windows only (pygame has its ow routines for this).
    Ramp should be provided as 3x256 or 3x1024 array in range 0:1.0

    On windows the first attempt to set the ramp doesn't always work. The parameter nAttemps
    allows the user to determine how many attempts should be made before failing
    """
    if newRamp.shape[0]!=3 and newRamp.shape[1]==3:
        newRamp= numpy.ascontiguousarray(newRamp.transpose())
    if sys.platform=='win32':
        newRamp= (255.0*newRamp).astype(numpy.uint16)
        newRamp.byteswap(True)#necessary, according to pyglet post from Martin Spacek
        for n in range(nAttempts):
            success = windll.gdi32.SetDeviceGammaRamp(pygletWindow._dc, newRamp.ctypes)
            if success:
                break
        assert success, 'SetDeviceGammaRamp failed'

    if sys.platform=='darwin':
        newRamp= (newRamp).astype(numpy.float32)
        LUTlength=newRamp.shape[1]
        error =carbon.CGSetDisplayTransferByTable(pygletWindow._screen.id, LUTlength,
                   newRamp[0,:].ctypes, newRamp[1,:].ctypes, newRamp[2,:].ctypes)
        assert not error, 'CGSetDisplayTransferByTable failed'

    if sys.platform.startswith('linux') and not _TravisTesting:
        newRamp= (65535*newRamp).astype(numpy.uint16)
        success = xf86vm.XF86VidModeSetGammaRamp(pygletWindow._x_display, pygletWindow._x_screen_id, 256,
                    newRamp[0,:].ctypes, newRamp[1,:].ctypes, newRamp[2,:].ctypes)
        assert success, 'XF86VidModeSetGammaRamp failed'

    elif _TravisTesting:
        logging.warn("It looks like we're running in the Travis-CI testing environment. Hardware gamma table cannot be set")
Ejemplo n.º 9
0
def getGammaRampSize(screenID, xDisplay=None, gammaErrorPolicy=None):
    """Returns the size of each channel of the gamma ramp."""

    if not gammaErrorPolicy:
        gammaErrorPolicy = defaultGammaErrorPolicy

    if sys.platform == 'win32' or _vmTesting:
        # windows documentation (for SetDeviceGammaRamp) seems to indicate that
        # the LUT size is always 256
        rampSize = 256
    elif sys.platform == 'darwin':
        rampSize = carbon.CGDisplayGammaTableCapacity(screenID)
    elif sys.platform.startswith('linux'):
        rampSize = ctypes.c_int()
        success = xf86vm.XF86VidModeGetGammaRampSize(xDisplay, screenID,
                                                     ctypes.byref(rampSize))
        if not success:
            func = 'XF86VidModeGetGammaRampSize'
            if gammaErrorPolicy == 'raise':
                raise OSError(raise_msg.format(func=func))
            elif gammaErrorPolicy == 'warn':
                logging.warning(warn_msg.format(func=func))
        else:
            rampSize = rampSize.value
    else:
        rampSize = 256

    if rampSize == 0:
        logging.warn(
            "The size of the gamma ramp was reported as 0. This can " +
            "mean that gamma settings have no effect. Proceeding with " +
            "a default gamma ramp size.")
        rampSize = 256

    return rampSize
Ejemplo n.º 10
0
def setGammaRamp(pygletWindow, newRamp, nAttempts=3):
    """Sets the hardware look-up table, using platform-specific ctypes functions.
    For use with pyglet windows only (pygame has its ow routines for this).
    Ramp should be provided as 3x256 or 3x1024 array in range 0:1.0

    On windows the first attempt to set the ramp doesn't always work. The parameter nAttemps
    allows the user to determine how many attempts should be made before failing
    """
    if newRamp.shape[0]!=3 and newRamp.shape[1]==3:
        newRamp= numpy.ascontiguousarray(newRamp.transpose())
    if sys.platform=='win32':
        newRamp= (255.0*newRamp).astype(numpy.uint16)
        newRamp.byteswap(True)#necessary, according to pyglet post from Martin Spacek
        for n in range(nAttempts):
            success = windll.gdi32.SetDeviceGammaRamp(0xFFFFFFFF & pygletWindow._dc, newRamp.ctypes) # FB 504
            if success:
                break
        assert success, 'SetDeviceGammaRamp failed'

    if sys.platform=='darwin':
        newRamp= (newRamp).astype(numpy.float32)
        LUTlength=newRamp.shape[1]
        error =carbon.CGSetDisplayTransferByTable(pygletWindow._screen.id, LUTlength,
                   newRamp[0,:].ctypes, newRamp[1,:].ctypes, newRamp[2,:].ctypes)
        assert not error, 'CGSetDisplayTransferByTable failed'

    if sys.platform.startswith('linux') and not _TravisTesting:
        newRamp= (65535*newRamp).astype(numpy.uint16)
        success = xf86vm.XF86VidModeSetGammaRamp(pygletWindow._x_display, pygletWindow._x_screen_id, 256,
                    newRamp[0,:].ctypes, newRamp[1,:].ctypes, newRamp[2,:].ctypes)
        assert success, 'XF86VidModeSetGammaRamp failed'

    elif _TravisTesting:
        logging.warn("It looks like we're running in the Travis-CI testing environment. Hardware gamma table cannot be set")
Ejemplo n.º 11
0
def wav2flac(path, keep=True):
    """Lossless compression: convert .wav file (on disk) to .flac format.

    If `path` is a directory name, convert all .wav files in the directory.

    `keep` to retain the original .wav file(s), default `True`.
    """
    flac_path = _getFlacPath()
    wav_files = []
    if path.endswith(".wav"):
        wav_files = [path]
    elif type(path) == str and os.path.isdir(path):
        wav_files = glob.glob(os.path.join(path, "*.wav"))
    if len(wav_files) == 0:
        logging.warn("failed to find .wav file(s) from %s" % path)
        return None
    flac_files = []
    for wavfile in wav_files:
        flacfile = wavfile.strip(".wav") + ".flac"
        flac_cmd = [flac_path, "-8", "-f", "--totally-silent", "-o", flacfile, wavfile]
        __, se = core.shellCall(flac_cmd, stderr=True)
        if se or not os.path.isfile(flacfile):  # just try again
            # ~2% incidence when recording for 1s, 650+ trials
            # never got two in a row; core.wait() does not help
            logging.warn("Failed to convert to .flac; trying again")
            __, se = core.shellCall(flac_cmd, stderr=True)
            if se:
                logging.error(se)
        if not keep:
            os.unlink(wavfile)
        flac_files.append(flacfile)
    if len(wav_files) == 1:
        return flac_files[0]
    else:
        return flac_files
Ejemplo n.º 12
0
    def setMouseType(self, name='arrow'):
        """Change the appearance of the cursor for this window. Cursor types
        provide contextual hints about how to interact with on-screen objects.

        The graphics used 'standard cursors' provided by the operating system.
        They may vary in appearance and hot spot location across platforms. The
        following names are valid on most platforms:

                'arrow' : Default pointer
                'ibeam' : Indicates text can be edited
            'crosshair' : Crosshair with hot-spot at center
                 'hand' : A pointing hand
              'hresize' : Double arrows pointing horizontally
              'vresize' : Double arrows pointing vertically

        Note, on Windows the 'crosshair' option is XORed with the background
        color. It will not be visible when placed over 50% grey fields.

        :param name: str, type of standard cursor to use
        :return:

        """
        try:
            glfw.set_cursor(self.winHandle, _CURSORS_[name])
        except KeyError:
            logging.warn(
                "Invalid cursor type name '{}', using default.".format(type))
            glfw.set_cursor(self.winHandle, _CURSORS_['arrow'])
Ejemplo n.º 13
0
    def load(self, filename=None):
        """If name is None then we'll try to save to
        """
        def parseLUTLine(line):
            return line.replace('[','').replace(']','').split(',')

        if filename is None:
            from psychopy import prefs
            filename = os.path.join(prefs.paths['userPrefsDir'], 'crs_bits.cfg')
        if os.path.exists(filename):
            config = configparser.RawConfigParser()
            with open(filename) as f:
                config.readfp(f)
            self.os = config.get('system','os')
            self.gfxCard = config.get('system','gfxCard')
            self.identityLUT = np.ones([256,3])
            self.identityLUT[:,0] = parseLUTLine(config.get('identityLUT','r'))
            self.identityLUT[:,1] = parseLUTLine(config.get('identityLUT','g'))
            self.identityLUT[:,2] = parseLUTLine(config.get('identityLUT','b'))
            return True
        else:
            logging.warn('no config file yet for %s' %self.bits)
            self.identityLUT = None
            self.gfxCard = None
            self.os = None
            return False
Ejemplo n.º 14
0
    def __init__(self,
                 project_file=None,
                 root_path=None,
                 osf=None,
                 name='',
                 autosave=True):
        self.autosave = autosave  # try to save file automatically on __del__
        self.project_file = project_file
        self.root_path = root_path  # overwrite previous (indexed) location
        self.name = name  # not needed but allows storing a short descr name
        # these will be update from project file loading if it exists
        self.index = []
        self.username = None
        self.project_id = None
        self.connected = False  # have we gone online yet?
        # load the project file (if exists) for info about previous sync
        if project_file:
            self.load(project_file)

        # check/set root_path
        if self.root_path is None:
            self.root_path = root_path  # use what we just loaded
        elif root_path not in [None, self.root_path]:
            logging.warn("The requested root_path and the previous root_path "
                         "differ. Using the requested path."
                         "given: {}"
                         "stored: {}".format(root_path, self.root_path))
        if self.root_path is None:
            logging.warn("Project file failed to load a root_path "
                         "for the local files and none was provided")

        self.osf = osf  # the self.osf is as property set on-access
Ejemplo n.º 15
0
    def load(self, filename=None):
        """If name is None then we'll try to save to
        """

        def parseLUTLine(line):
            return line.replace("[", "").replace("]", "").split(",")

        if filename is None:
            from psychopy import prefs

            filename = os.path.join(prefs.paths["userPrefsDir"], "crs_bits.cfg")
        if os.path.exists(filename):
            config = configparser.RawConfigParser()
            with open(filename) as f:
                config.readfp(f)
            self.os = config.get("system", "os")
            self.gfxCard = config.get("system", "gfxCard")
            self.identityLUT = np.ones([256, 3])
            _idLUT = "identityLUT"
            self.identityLUT[:, 0] = parseLUTLine(config.get(_idLUT, "r"))
            self.identityLUT[:, 1] = parseLUTLine(config.get(_idLUT, "g"))
            self.identityLUT[:, 2] = parseLUTLine(config.get(_idLUT, "b"))
            return True
        else:
            logging.warn("no config file yet for %s" % self.bits)
            self.identityLUT = None
            self.gfxCard = None
            self.os = None
            return False
Ejemplo n.º 16
0
    def __init__(self, project_file=None, root_path=None, osf=None,
                 name='', autosave=True):
        self.autosave = autosave  # try to save file automatically on __del__
        self.project_file = project_file
        self.root_path = root_path  # overwrite previous (indexed) location
        self.name = name  # not needed but allows storing a short descr name
        # these will be update from project file loading if it exists
        self.index = []
        self.username = None
        self.project_id = None
        self.connected = False  # have we gone online yet?
        # load the project file (if exists) for info about previous sync
        if project_file:
            self.load(project_file)

        # check/set root_path
        if self.root_path is None:
            self.root_path = root_path  # use what we just loaded
        elif root_path not in [None, self.root_path]:
            logging.warn("The requested root_path and the previous root_path "
                         "differ. Using the requested path."
                         "given: {}"
                         "stored: {}".format(root_path, self.root_path))
        if self.root_path is None:
            logging.warn("Project file failed to load a root_path "
                         "for the local files and none was provided")

        self.osf = osf  # the self.osf is as property set on-access
Ejemplo n.º 17
0
def _bestDriver(devNames, devIDs):
    """Find ASIO or Windows sound drivers
    """
    preferredDrivers = prefs.general['audioDriver']
    outputID = None
    audioDriver = None
    osEncoding = sys.getfilesystemencoding()
    for prefDriver in preferredDrivers:
        logging.info('Looking for {}'.format(prefDriver))
        if prefDriver.lower() == 'directsound':
            prefDriver = u'Primary Sound'
        # look for that driver in available devices
        for devN, devString in enumerate(devNames):
            logging.info('Examining for {}'.format(devString))
            try:
                ds = devString.decode(osEncoding).encode('utf-8').lower()
                if prefDriver.encode('utf-8').lower() in ds:
                    audioDriver = devString.decode(osEncoding).encode('utf-8')
                    outputID = devIDs[devN]
                    logging.info('Success: {}'.format(devString))
                    # we found a driver don't look for others
                    return audioDriver, outputID
            except (UnicodeDecodeError, UnicodeEncodeError):
                logging.info('Failed: {}'.format(devString))
                logging.warn('find best sound driver - could not '
                             'interpret unicode in driver name')
    else:
        return None, None
Ejemplo n.º 18
0
def flac2wav(path, keep=True):
    """Uncompress: convert .flac file (on disk) to .wav format (new file).

    If `path` is a directory name, convert all .flac files in the directory.

    `keep` to retain the original .flac file(s), default `True`.
    """
    flac_path = _getFlacPath()
    flac_files = []
    if path.endswith('.flac'):
        flac_files = [path]
    elif type(path) == str and os.path.isdir(path):
        flac_files = glob.glob(os.path.join(path, '*.flac'))
    if len(flac_files) == 0:
        logging.warn('failed to find .flac file(s) from %s' % path)
        return None
    wav_files = []
    for flacfile in flac_files:
        wavname = flacfile.strip('.flac') + '.wav'
        flac_cmd = [flac_path, "-d", "--totally-silent",
                    "-f", "-o", wavname, flacfile]
        _junk, se = core.shellCall(flac_cmd, stderr=True)
        if se:
            logging.error(se)
        if not keep:
            os.unlink(flacfile)
        wav_files.append(wavname)
    if len(wav_files) == 1:
        return wav_files[0]
    else:
        return wav_files
Ejemplo n.º 19
0
def _bestDriver(devNames, devIDs):
    """Find ASIO or Windows sound drivers
    """
    preferredDrivers = prefs.general['audioDriver']
    outputID = None
    audioDriver = None
    osEncoding = sys.getfilesystemencoding()
    for prefDriver in preferredDrivers:
        logging.info('Looking for {}'.format(prefDriver))
        if prefDriver.lower() == 'directsound':
            prefDriver = u'Primary Sound'
        # look for that driver in available devices
        for devN, devString in enumerate(devNames):
            logging.info('Examining for {}'.format(devString))
            try:
                ds = devString.decode(osEncoding).encode('utf-8').lower()
                if prefDriver.encode('utf-8').lower() in ds:
                    audioDriver = devString.decode(osEncoding).encode('utf-8')
                    outputID = devIDs[devN]
                    logging.info('Success: {}'.format(devString))
                    # we found a driver don't look for others
                    return audioDriver, outputID
            except (UnicodeDecodeError, UnicodeEncodeError):
                logging.info('Failed: {}'.format(devString))
                logging.warn('find best sound driver - could not '
                             'interpret unicode in driver name')
    else:
        return None, None
Ejemplo n.º 20
0
    def __init__(self, win, size, pos=(0,0), ori=0, nVert=120, shape='circle', units=None,
            name='', autoLog=True):
        #what local vars are defined (these are the init params) for use by __repr__
        self._initParams = dir()
        self._initParams.remove('self')
        #set self params
        self.autoLog=False #set this False first and change after attribs are set
        self.win=win
        self.name = name
        self.ori = ori
        #unit conversions
        if units!=None and len(units):
            self.units = units
        else:
            self.units = win.units

        # ugly hack for setting vertices using combination of shape and nVerts
        if type(nVert) == int:
            self.nVert = nVert
        regularPolygon = True
        self.shape = shape
        unrecognized = False
        if shape is None:
            pass #just use the nVert we were given
        elif type(shape) in [str, unicode]:
            if shape.lower() == 'circle':
                pass #just use the nVert we were given
            elif shape.lower() == 'square':
                regularPolygon = False # if we use polygon then we have to hack the orientation
                vertices = [[0.5,-0.5],[-0.5,-0.5],[-0.5,0.5],[0.5,0.5]]
            elif shape.lower() == 'triangle':
                regularPolygon = False # if we use polygon then we have to hack the orientation
                vertices = [[0.5,-0.5],[0,0.5],[-0.5,-0.5]]
            else:
                unrecognized = True
        elif type(shape) in [tuple, list, numpy.ndarray]:
            regularPolygon = False
            vertices = shape
        else:
            unrecognized = True
        if unrecognized:
            logging.warn("Unrecognized shape for aperture. Expected 'circle', 'square', 'triangle', vertices or None but got %s" %(repr(shape)))
        if regularPolygon:
            self._shape = polygon.Polygon(win=self.win, edges=self.nVert,
                                          fillColor=1, lineColor=None,
                                          interpolate=False,
                                          pos=pos,
                                          size=size)
        else:
            self._shape = ShapeStim(win=self.win, vertices=vertices,
                                          fillColor=1, lineColor=None,
                                          interpolate=False,
                                          pos=pos,
                                          size=size)

        self._needVertexUpdate = True
        self._reset()#implicitly runs an self.enable()
        self.autoLog= autoLog
        if autoLog:
            logging.exp("Created %s = %s" %(self.name, str(self)))
Ejemplo n.º 21
0
def wav2flac(path, keep=True):
    """Lossless compression: convert .wav file (on disk) to .flac format.

    If `path` is a directory name, convert all .wav files in the directory.

    `keep` to retain the original .wav file(s), default `True`.
    """
    flac_path = _getFlacPath()
    wav_files = []
    if path.endswith('.wav'):
        wav_files = [path]
    elif type(path) == str and os.path.isdir(path):
        wav_files = glob.glob(os.path.join(path, '*.wav'))
    if len(wav_files) == 0:
        logging.warn('failed to find .wav file(s) from %s' % path)
        return None
    flac_files = []
    for wavfile in wav_files:
        flacfile = wavfile.strip('.wav') + '.flac'
        flac_cmd = [flac_path, "-8", "-f", "--totally-silent", "-o", flacfile, wavfile]
        __, se = core.shellCall(flac_cmd, stderr=True)
        if se or not os.path.isfile(flacfile): # just try again
            # ~2% incidence when recording for 1s, 650+ trials
            # never got two in a row; core.wait() does not help
            logging.warn('Failed to convert to .flac; trying again')
            __, se = core.shellCall(flac_cmd, stderr=True)
            if se:
                logging.error(se)
        if not keep:
            os.unlink(wavfile)
        flac_files.append(flacfile)
    if len(wav_files) == 1:
        return flac_files[0]
    else:
        return flac_files
Ejemplo n.º 22
0
    def load(self, filename=None):
        """If name is None then we'll try to save to
        """
        def parseLUTLine(line):
            return line.replace('[', '').replace(']', '').split(',')

        if filename is None:
            from psychopy import prefs
            filename = os.path.join(prefs.paths['userPrefsDir'],
                                    'crs_bits.cfg')
        if os.path.exists(filename):
            config = configparser.RawConfigParser()
            with open(filename) as f:
                config.readfp(f)
            self.os = config.get('system', 'os')
            self.gfxCard = config.get('system', 'gfxCard')
            self.identityLUT = np.ones([256, 3])
            _idLUT = 'identityLUT'
            self.identityLUT[:, 0] = parseLUTLine(config.get(_idLUT, 'r'))
            self.identityLUT[:, 1] = parseLUTLine(config.get(_idLUT, 'g'))
            self.identityLUT[:, 2] = parseLUTLine(config.get(_idLUT, 'b'))
            return True
        else:
            logging.warn('no config file yet for %s' % self.bits)
            self.identityLUT = None
            self.gfxCard = None
            self.os = None
            return False
Ejemplo n.º 23
0
    def writeWindowCode(self, buff):
        """ setup the window code
        """
        buff.writeIndentedLines("\n# Setup the Window\n")
        #get parameters for the Window
        fullScr = self.params['Full-screen window'].val
        allowGUI = (not bool(fullScr)) or bool(
            self.params['Show mouse'].val
        )  #if fullscreen then hide the mouse, unless its requested explicitly
        allowStencil = False
        for thisRoutine in self.exp.routines.values():  #NB routines is a dict
            for thisComp in thisRoutine:  #a single routine is a list of components
                if thisComp.type == 'Aperture': allowStencil = True
                if thisComp.type == 'RatingScale':
                    allowGUI = True  # to have a mouse; BUT might not want it shown in other routines

        requestedScreenNumber = int(self.params['Screen'].val)
        if requestedScreenNumber > wx.Display.GetCount():
            logging.warn(
                "Requested screen can't be found. Writing script using first available screen."
            )
            screenNumber = 0
        else:
            screenNumber = requestedScreenNumber - 1  #computer has 1 as first screen

        if fullScr:
            size = wx.Display(screenNumber).GetGeometry()[2:4]
        else:
            size = self.params['Window size (pixels)']
        buff.writeIndented(
            "win = visual.Window(size=%s, fullscr=%s, screen=%s, allowGUI=%s, allowStencil=%s,\n"
            % (size, fullScr, screenNumber, allowGUI, allowStencil))
        buff.writeIndented(
            "    monitor=%(Monitor)s, color=%(color)s, colorSpace=%(colorSpace)s,\n"
            % (self.params))
        if self.params['blendMode'].val:
            buff.writeIndented("    blendMode=%(blendMode)s, useFBO=True,\n" %
                               (self.params))

        if self.params['Units'].val == 'use prefs':
            buff.write("    )\n")
        else:
            buff.write("    units=%s)\n" % self.params['Units'])

        if 'microphone' in self.exp.psychopyLibs:  # need a pyo Server
            buff.writeIndentedLines("\n# Enable sound input/output:\n" +
                                    "microphone.switchOn()\n")

        buff.writeIndented(
            "# store frame rate of monitor if we can measure it successfully\n"
        )
        buff.writeIndented("expInfo['frameRate']=win.getActualFrameRate()\n")
        buff.writeIndented("if expInfo['frameRate']!=None:\n")
        buff.writeIndented("    frameDur = 1.0/round(expInfo['frameRate'])\n")
        buff.writeIndented("else:\n")
        buff.writeIndented(
            "    frameDur = 1.0/60.0 # couldn't get a reliable measure so guess\n"
        )
Ejemplo n.º 24
0
def getGammaRamp(screenID, xDisplay=None, gammaErrorPolicy='raise'):
    """Ramp will be returned as 3xN array in range 0:1
    """

    rampSize = getGammaRampSize(screenID, xDisplay=xDisplay)

    if sys.platform == 'win32':
        # init R, G, and B ramps
        origramps = numpy.empty((3, rampSize), dtype=numpy.uint16)
        success = windll.gdi32.GetDeviceGammaRamp(screenID,
                                                  origramps.ctypes)  # FB 504
        if not success:
            func = 'GetDeviceGammaRamp'
            if gammaErrorPolicy == 'raise':
                raise OSError(raise_msg.format(func=func))
            elif gammaErrorPolicy == 'warn':
                logging.warning(warn_msg.format(func=func))
        else:
            origramps.byteswap(True)  # back to 0:255
            origramps = origramps / 255.0  # rescale to 0:1

    if sys.platform == 'darwin':
        # init R, G, and B ramps
        origramps = numpy.empty((3, rampSize), dtype=numpy.float32)
        n = numpy.empty([1], dtype=numpy.int)
        error = carbon.CGGetDisplayTransferByTable(screenID, rampSize,
                                                   origramps[0, :].ctypes,
                                                   origramps[1, :].ctypes,
                                                   origramps[2, :].ctypes,
                                                   n.ctypes)
        if error:
            func = 'CGSetDisplayTransferByTable'
            if gammaErrorPolicy == 'raise':
                raise OSError(raise_msg.format(func=func))
            elif gammaErrorPolicy == 'warn':
                logging.warning(warn_msg.format(func=func))

    if sys.platform.startswith('linux') and not _TravisTesting:
        origramps = numpy.empty((3, rampSize), dtype=numpy.uint16)
        success = xf86vm.XF86VidModeGetGammaRamp(xDisplay, screenID, rampSize,
                                                 origramps[0, :].ctypes,
                                                 origramps[1, :].ctypes,
                                                 origramps[2, :].ctypes)
        if not success:
            func = 'XF86VidModeGetGammaRamp'
            if gammaErrorPolicy == 'raise':
                raise OSError(raise_msg.format(func=func))
            elif gammaErrorPolicy == 'warn':
                logging.warning(warn_msg.format(func=func))
        else:
            origramps = origramps / 65535.0  # rescale to 0:1

    elif _TravisTesting:
        logging.warn("It looks like we're running in the Travis-CI testing "
                     "environment. Hardware gamma table cannot be retrieved")
        origramps = None

    return origramps
Ejemplo n.º 25
0
    def resample(self, newRate=16000, keep=True, log=True):
        """Re-sample the saved file to a new rate, return the full path.

        Can take several visual frames to resample a 2s recording.

        The default values for resample() are for google-speech, keeping the
        original (presumably recorded at 48kHz) to archive.
        A warning is generated if the new rate not an integer factor / multiple of the old rate.

        To control anti-aliasing, use pyo.downsamp() or upsamp() directly.
        """
        if not self.savedFile or not os.path.isfile(self.savedFile):
            msg = "%s: Re-sample requested but no saved file" % self.loggingId
            logging.error(msg)
            raise ValueError(msg)
        if newRate <= 0 or type(newRate) != int:
            msg = "%s: Re-sample bad new rate = %s" % (self.loggingId, repr(newRate))
            logging.error(msg)
            raise ValueError(msg)

        # set-up:
        if self.rate >= newRate:
            ratio = float(self.rate) / newRate
            info = "-ds%i" % ratio
        else:
            ratio = float(newRate) / self.rate
            info = "-us%i" % ratio
        if ratio != int(ratio):
            logging.warn("%s: old rate is not an integer factor of new rate" % self.loggingId)
        ratio = int(ratio)
        newFile = info.join(os.path.splitext(self.savedFile))

        # use pyo's downsamp or upsamp based on relative rates:
        if not ratio:
            logging.warn("%s: Re-sample by %sx is undefined, skipping" % (self.loggingId, str(ratio)))
        elif self.rate >= newRate:
            t0 = core.getTime()
            downsamp(self.savedFile, newFile, ratio)  # default 128-sample anti-aliasing
            if log and self.autoLog:
                logging.exp(
                    "%s: Down-sampled %sx in %.3fs to %s" % (self.loggingId, str(ratio), core.getTime() - t0, newFile)
                )
        else:
            t0 = core.getTime()
            upsamp(self.savedFile, newFile, ratio)  # default 128-sample anti-aliasing
            if log and self.autoLog:
                logging.exp(
                    "%s: Up-sampled %sx in %.3fs to %s" % (self.loggingId, str(ratio), core.getTime() - t0, newFile)
                )

        # clean-up:
        if not keep:
            os.unlink(self.savedFile)
            self.savedFile = newFile
            self.rate = newRate

        return os.path.abspath(newFile)
Ejemplo n.º 26
0
 def run_event(self):
     if self.event == 'exit':
         logging.info("Exiting. . .")
         self.window.close()
         core.quit()
     if self.event in ['nothing', 'continue']:
         pass
     else:
         logging.warn("Event not recognized. Doing nothing.")
Ejemplo n.º 27
0
 def _create_window(self):
     """ Creates a window based on the settings and calculates framerate. """
     win = Window(monitor=self.monitor.name, **self.settings['window'])
     win.flip(clearBuffer=True)
     self.actual_framerate = win.getActualFrameRate()
     t_per_frame = 1. / self.actual_framerate
     logging.warn(f"Actual framerate: {self.actual_framerate:.5f} "
                  f"(1 frame = {t_per_frame:.5f})")
     return win
Ejemplo n.º 28
0
 def run_event(self):
     if self.event == 'exit':
         logging.info("Exiting. . .")
         self.window.close()
         core.quit()
     if self.event in ['nothing', 'continue']:
         pass
     else:
         logging.warn("Event not recognized. Doing nothing.")
Ejemplo n.º 29
0
 def setUseShaders(self, val=True):
     """Set this stimulus to use shaders if possible.
     """
     if val==True and self.win._haveShaders==False:
         logging.warn("Shaders were requested but aren;t available. Shaders need OpenGL 2.0+ drivers")
     if val!=self.useShaders:
         self.useShaders=val
         self._needSetText=True
         self._needUpdate = True
Ejemplo n.º 30
0
 def run_event(self):
     if self.event == "exit":
         logging.info("Exiting. . .")
         self.window.close()
         core.quit()
     if self.event in ["nothing", "continue"]:
         pass
     else:
         logging.warn("Event not recognized. Doing nothing.")
Ejemplo n.º 31
0
 def setUseShaders(self, val=True):
     """Set this stimulus to use shaders if possible.
     """
     if val==True and self.win._haveShaders==False:
         logging.warn("Shaders were requested but aren;t available. Shaders need OpenGL 2.0+ drivers")
     if val!=self.useShaders:
         self.useShaders=val
         self._needSetText=True
         self._needUpdate = True
Ejemplo n.º 32
0
    def __init__(self, output_str, subject=None, output_dir=None, settings_file=None):
        super().__init__(output_str, subject=subject,
                         output_dir=output_dir, settings_file=settings_file, run=run, eyetracker_on=False)

        logging.warn(self.settings['run'])
        self.buttons = self.settings['various'].get('buttons')
        self.image2 = ImageStim(self.win,
                                       self.settings['pile'].get('image2'),
                                       texRes=32,
                                       size=self.settings['pile'].get('dot_radius'))
Ejemplo n.º 33
0
 def quickCheck(self):
     """Check whether the current graphics card and OS match those of the last saved LUT
     """
     if self._getGfxCardString() != self.gfxCard:
         logging.warn("The graphics card or its driver has changed. We'll re-check the identity LUT for the card")
         return 0
     if self._getOSstring() != self.os:
         logging.warn("The OS has been changed/updated. We'll re-check the identity LUT for the card")
         return 0
     return 1 #all seems the same as before
Ejemplo n.º 34
0
 def quickCheck(self):
     """Check whether the current graphics card and OS match those of the last saved LUT
     """
     if self._getGfxCardString() != self.gfxCard:
         logging.warn("The graphics card or its driver has changed. We'll re-check the identity LUT for the card")
         return 0
     if self._getOSstring() != self.os:
         logging.warn("The OS has been changed/updated. We'll re-check the identity LUT for the card")
         return 0
     return 1 #all seems the same as before
Ejemplo n.º 35
0
 def _warnTesting(self):
     msg = "We need to run some tests on your graphics card (hopefully just once).\n" + \
         "The BitsSharp will go into status mode while this is done.\n" + \
         "It can take a minute of two."
     logging.warn(msg)
     logging.flush()
     msgOnScreen = visual.TextStim(self.win, msg)
     msgOnScreen.draw()
     self.win.flip()
     core.wait(1.0)
     self.win.flip()
Ejemplo n.º 36
0
 def _warnTesting(self):
     msg = "We need to run some tests on your graphics card (hopefully just once). " + \
         "The BitsSharp will go into status mode while this is done. " + \
         "It can take a minute or two."
     logging.warn(msg)
     logging.flush()
     msgOnScreen = visual.TextStim(self.win, msg)
     msgOnScreen.draw()
     self.win.flip()
     core.wait(1.0)
     self.win.flip()
Ejemplo n.º 37
0
    def __init__(self, outpath, nameDict, first_columns):
        self.columns = nameDict.keys()
        self.outpath = outpath
        self.outdir = os.path.dirname(outpath)

        if len(self.columns) != len(set(self.columns)):
            logging.warn("There are duplicate file names in the logfile!")

        self.data = pd.DataFrame(columns=self.columns)
        self.defaultTrial = nameDict
        self.curRowIdx = 0
        self.first_columns = first_columns
Ejemplo n.º 38
0
 def _create_window(self):
     """ Creates a window based on the settings and calculates framerate. """
     win = Window(monitor=self.monitor.name, **self.settings['window'])
     win.flip(clearBuffer=True)
     self.actual_framerate = win.getActualFrameRate()
     if self.actual_framerate is None:
         logging.warn("framerate not measured, substituting 60 by default")
         self.actual_framerate = 60.0
     t_per_frame = 1. / self.actual_framerate
     logging.warn(f"Actual framerate: {self.actual_framerate:.5f} "
                  f"(1 frame = {t_per_frame:.5f})")
     return win
Ejemplo n.º 39
0
 def setUser(self, user):
     if user == self._user:
         return  # nothing to do here. Move along please.
     self._user = user
     try:
         self.app.osf_session = pyosf.Session(user)
     except pyosf.AuthError:
         print("failed to authenticate - probably need 2FA")
     except requests.exceptions.ConnectionError:
         logging.warn("Connection error trying to connect to pyosf")
     ProjectsMenu.appData['user'] = user
     if self.searchDlg:
         self.searchDlg.updateUserProjs()
Ejemplo n.º 40
0
 def setUser(self, user):
     if user == self._user:
         return  # nothing to do here. Move along please.
     self._user = user
     try:
         self.app.osf_session = pyosf.Session(user)
     except pyosf.AuthError:
         print("failed to authenticate - probably need 2FA")
     except requests.exceptions.ConnectionError:
         logging.warn("Connection error trying to connect to pyosf")
     ProjectsMenu.appData['user'] = user
     if self.searchDlg:
         self.searchDlg.updateUserProjs()
Ejemplo n.º 41
0
def get_output_dir_str(subject, session, task, run):
    output_dir = op.join(op.dirname(__file__), 'logs', f'sub-{subject}')
    logging.warn(f'Writing results to  {output_dir}')

    if session:
        output_dir = op.join(output_dir, f'ses-{session}')
        output_str = f'sub-{subject}_ses-{session}_task-{task}'
    else:
        output_str = f'sub-{subject}_task-{task}'

    if run:
        output_str += f'_run-{run}'

    return output_dir, output_str
Ejemplo n.º 42
0
 def oneAttempt():
     self.com.flushInput()
     self.sendMessage('$GetVideoLine=[%i, %i]\r' %(lineN, nPixels))
     #prepare to read
     t0 = time.time()
     raw=""
     vals=[]
     while len(vals)<(nPixels*3):
         raw += self.read(timeout=0.001)
         vals = raw.split(';')[1:-1]
         if  (time.time()-t0)>timeout:
             logging.warn("getVideoLine() timed out: only found %i pixels in %.2f s" %(len(vals), timeout))
             break
     return np.array(vals, dtype=int).reshape([-1,3])
Ejemplo n.º 43
0
    def writeWindowCode(self,buff):
        """ setup the window code
        """
        buff.writeIndentedLines("\n# Setup the Window\n")
        #get parameters for the Window
        fullScr = self.params['Full-screen window'].val
        allowGUI = (not bool(fullScr)) or bool(self.params['Show mouse'].val) #if fullscreen then hide the mouse, unless its requested explicitly
        allowStencil = False
        for thisRoutine in self.exp.routines.values(): #NB routines is a dict
           for thisComp in thisRoutine: #a single routine is a list of components
               if thisComp.type=='Aperture': allowStencil = True
               if thisComp.type=='RatingScale': allowGUI = True # to have a mouse; BUT might not want it shown in other routines

        requestedScreenNumber = int(self.params['Screen'].val)
        try:
            nScreens = wx.Display.GetCount()
        except:
		    nScreens = 10 #will fail if application hasn't been created (e.g. in test environments)
        if requestedScreenNumber > nScreens:
            logging.warn("Requested screen can't be found. Writing script using first available screen.")
            screenNumber = 0
        else:
            screenNumber = requestedScreenNumber-1 #computer has 1 as first screen

        if fullScr:
            size = wx.Display(screenNumber).GetGeometry()[2:4]
        else:
            size=self.params['Window size (pixels)']
        buff.writeIndented("win = visual.Window(size=%s, fullscr=%s, screen=%s, allowGUI=%s, allowStencil=%s,\n" %
                           (size, fullScr, screenNumber, allowGUI, allowStencil))
        buff.writeIndented("    monitor=%(Monitor)s, color=%(color)s, colorSpace=%(colorSpace)s,\n" %(self.params))
        if self.params['blendMode'].val:
            buff.writeIndented("    blendMode=%(blendMode)s, useFBO=True,\n" %(self.params))

        if self.params['Units'].val=='use prefs':
            buff.write("    )\n")
        else:
            buff.write("    units=%s)\n" %self.params['Units'])

        if 'microphone' in self.exp.psychopyLibs: # need a pyo Server
            buff.writeIndentedLines("\n# Enable sound input/output:\n"+
                                "microphone.switchOn()\n")

        buff.writeIndented("# store frame rate of monitor if we can measure it successfully\n")
        buff.writeIndented("expInfo['frameRate'] = win.getActualFrameRate()\n")
        buff.writeIndented("if expInfo['frameRate'] != None:\n")
        buff.writeIndented("    frameDur = 1.0 / round(expInfo['frameRate'])\n")
        buff.writeIndented("else:\n")
        buff.writeIndented("    frameDur = 1.0 / 60.0  # couldn't get a reliable measure so guess\n")
Ejemplo n.º 44
0
 def oneAttempt():
     self.com.flushInput()
     self.sendMessage('$GetVideoLine=[%i, %i]\r' %(lineN, nPixels))
     self.__dict__['mode'] = 'status' #the box implicitly ends up in status mode
     #prepare to read
     t0 = time.time()
     raw=""
     vals=[]
     while len(vals)<(nPixels*3):
         raw += self.read(timeout=0.001)
         vals = raw.split(';')[1:-1]
         if  (time.time()-t0)>timeout:
             logging.warn("getVideoLine() timed out: only found %i pixels in %.2f s" %(len(vals), timeout))
             return []
     return np.array(vals, dtype=int).reshape([-1,3])
Ejemplo n.º 45
0
    def complete(self):
        """Completes the period, using up whatever time is remaining with a call to wait()

        :return: 1 for success, 0 for fail (the period overran)
        """
        self.status=FINISHED
        timeRemaining = self.countdown.getTime()
        if self.win:
            self.win.recordFrameIntervals = self._winWasRecordingIntervals
        if timeRemaining<0:
            logging.warn('We overshot the intended duration of %s by %.4fs. The intervening code took too long to execute.' %(self.name, abs(timeRemaining)))
            return 0
        else:
            wait(timeRemaining)
            return 1
Ejemplo n.º 46
0
    def saveAsJson(self,
                   fileName=None,
                   encoding='utf-8',
                   fileCollisionMethod='rename'):
        """
        Serialize the object to the JSON format.

        Parameters
        ----------
        fileName: string, or None
            the name of the file to create or append. Can include a relative or
            absolute path. If `None`, will not write to a file, but return an
            in-memory JSON object.

        encoding : string, optional
            The encoding to use when writing the file. This parameter will be
            ignored if `append` is `False` and `fileName` ends with `.psydat`
            or `.npy` (i.e. if a binary file is to be written).

        fileCollisionMethod : string
            Collision method passed to
            :func:`~psychopy.tools.fileerrortools.handleFileCollision`. Can be
            either of `'rename'`, `'overwrite'`, or `'fail'`.

        Notes
        -----
        Currently, a copy of the object is created, and the copy's .origin
        attribute is set to an empty string before serializing
        because loading the created JSON file would sometimes fail otherwise.

        """
        fileName = pathToString(fileName)

        self_copy = copy.deepcopy(self)
        self_copy.origin = ''
        msg = ('Setting attribute .origin to empty string during JSON '
               'serialization.')
        logging.warn(msg)

        if (fileName is None) or (fileName == 'stdout'):
            return json_tricks.dumps(self_copy)
        else:
            with openOutputFile(fileName=fileName,
                                fileCollisionMethod=fileCollisionMethod,
                                encoding=encoding) as f:
                json_tricks.dump(self_copy, f)

            logging.info('Saved JSON data to %s' % f.name)
Ejemplo n.º 47
0
    def saveAsJson(self,
                   fileName=None,
                   encoding='utf-8',
                   fileCollisionMethod='rename'):
        """
        Serialize the object to the JSON format.

        Parameters
        ----------
        fileName: string, or None
            the name of the file to create or append. Can include a relative or
            absolute path. If `None`, will not write to a file, but return an
            in-memory JSON object.

        encoding : string, optional
            The encoding to use when writing the file. This parameter will be
            ignored if `append` is `False` and `fileName` ends with `.psydat`
            or `.npy` (i.e. if a binary file is to be written).

        fileCollisionMethod : string
            Collision method passed to
            :func:`~psychopy.tools.fileerrortools.handleFileCollision`. Can be
            either of `'rename'`, `'overwrite'`, or `'fail'`.

        Notes
        -----
        Currently, a copy of the object is created, and the copy's .origin
        attribute is set to an empty string before serializing
        because loading the created JSON file would sometimes fail otherwise.

        """
        self_copy = copy.deepcopy(self)
        self_copy.origin = ''
        msg = ('Setting attribute .origin to empty string during JSON '
               'serialization.')
        logging.warn(msg)

        if fileName is None:
            return json_tricks.np.dumps(self_copy)
        else:
            f = openOutputFile(fileName,
                               fileCollisionMethod=fileCollisionMethod,
                               encoding=encoding)
            json_tricks.np.dump(self_copy, f)

            if f != sys.stdout:
                f.close()
                logging.info('Saved JSON data to %s' % f.name)
Ejemplo n.º 48
0
    def __init__(self,
                 output_str,
                 subject=None,
                 output_dir=None,
                 settings_file=None,
                 run=None,
                 eyetracker_on=False):
        print(settings_file)
        super().__init__(output_str,
                         subject=subject,
                         output_dir=output_dir,
                         settings_file=settings_file,
                         run=run,
                         eyetracker_on=eyetracker_on)

        logging.warn(self.settings['run'])
Ejemplo n.º 49
0
    def _load_settings(self):
        """ Loads settings and sets preferences. """
        if self.settings_file is None:
            self.settings_file = op.join(op.dirname(__file__), 'default_settings.yml')
            logging.warn(f"Using default logfile ({self.settings_file}")

        with open(self.settings_file, 'r') as f_in:
            settings = yaml.load(f_in)

        exp_prefs = settings['preferences']  # set preferences globally
        for preftype, these_settings in exp_prefs.items():
            for key, value in these_settings.items():
                pref_subclass = getattr(psychopy_prefs, preftype)
                pref_subclass[key] = value
                setattr(psychopy_prefs, preftype, pref_subclass)

        return settings
Ejemplo n.º 50
0
 def oneAttempt():
     self.com.flushInput()
     self.sendMessage("$GetVideoLine=[%i, %i]\r" % (lineN, nPixels))
     # the box implicitly ends up in status mode
     self.__dict__["mode"] = "status"
     # prepare to read
     t0 = time.time()
     raw = ""
     vals = []
     while len(vals) < (nPixels * 3):
         raw += self.read(timeout=0.001)
         vals = raw.split(";")[1:-1]
         if time.time() - t0 > timeout:
             msg = "getVideoLine() timed out: only found %i pixels" " in %.2f s"
             logging.warn(msg % (len(vals), timeout))
             return []
     return np.array(vals, dtype=int).reshape([-1, 3])
Ejemplo n.º 51
0
    def saveAsJson(self,
                   fileName=None,
                   encoding='utf-8',
                   fileCollisionMethod='rename'):
        """
        Serialize the object to the JSON format.

        Parameters
        ----------
        fileName: string, or None
            the name of the file to create or append. Can include a relative or
            absolute path. If `None`, will not write to a file, but return an
            in-memory JSON object.

        encoding : string, optional
            The encoding to use when writing the file.

        fileCollisionMethod : string
            Collision method passed to
            :func:`~psychopy.tools.fileerrortools.handleFileCollision`. Can be
            either of `'rename'`, `'overwrite'`, or `'fail'`.

        Notes
        -----
        Currently, a copy of the object is created, and the copy's .origin
        attribute is set to an empty string before serializing
        because loading the created JSON file would sometimes fail otherwise.

        """
        fileName = pathToString(fileName)

        self_copy = copy.deepcopy(self)
        self_copy.origin = ''
        msg = ('Setting attribute .origin to empty string during JSON '
               'serialization.')
        logging.warn(msg)

        if (fileName is None) or (fileName == 'stdout'):
            return json_tricks.dumps(self_copy)
        else:
            with openOutputFile(fileName=fileName,
                                fileCollisionMethod=fileCollisionMethod,
                                encoding=encoding) as f:
                json_tricks.dump(self_copy, f)

            logging.info('Saved JSON data to %s' % f.name)
Ejemplo n.º 52
0
    def complete(self):
        """Completes the period, using up whatever time is remaining with a call to wait()

        :return: 1 for success, 0 for fail (the period overran)
        """
        self.status = FINISHED
        timeRemaining = self.countdown.getTime()
        if self.win:
            self.win.recordFrameIntervals = self._winWasRecordingIntervals
        if timeRemaining < 0:
            logging.warn(
                'We overshot the intended duration of %s by %.4fs. The intervening code took too long to execute.'
                % (self.name, abs(timeRemaining)))
            return 0
        else:
            wait(timeRemaining)
            return 1
Ejemplo n.º 53
0
    def load_next_trial(self, phase_dur):
        self.draw()  # draw this phase, then load
        self.session.win.flip()

        load_start = self.session.clock.getTime()
        try:
            self.session.create_trial(self.trial_nr+1)
        except Exception as err:  # not quite happy about this try/except part ...
            logging.warn('Cannot create trial - probably at last one '
                            f'(trial {self.trial_nr})!')
            raise(err)

        load_dur = self.session.clock.getTime() - load_start

        if load_dur > phase_dur:  # overshoot! not good!
            logging.warn(f'Time to load stimulus ({load_dur:.5f}) is longer than'
                            f' phase-duration {phase_dur:.5f} (trial {self.trial_nr})!')
Ejemplo n.º 54
0
def getGammaRamp(screenID, xDisplay=None):
    """Ramp will be returned as 3xN array in range 0:1
    """

    rampSize = getGammaRampSize(screenID, xDisplay=xDisplay)

    if sys.platform == 'win32':
        # init R, G, and B ramps
        origramps = numpy.empty((3, rampSize), dtype=numpy.uint16)
        success = windll.gdi32.GetDeviceGammaRamp(
            screenID, origramps.ctypes)  # FB 504
        if not success:
            raise AssertionError('GetDeviceGammaRamp failed')
        origramps.byteswap(True)  # back to 0:255
        origramps = origramps/255.0  # rescale to 0:1

    if sys.platform == 'darwin':
        # init R, G, and B ramps
        origramps = numpy.empty((3, rampSize), dtype=numpy.float32)
        n = numpy.empty([1], dtype=numpy.int)
        error = carbon.CGGetDisplayTransferByTable(
            screenID, rampSize,
            origramps[0, :].ctypes,
            origramps[1, :].ctypes,
            origramps[2, :].ctypes, n.ctypes)
        if error:
            raise AssertionError('CGSetDisplayTransferByTable failed')

    if sys.platform.startswith('linux') and not _TravisTesting:
        origramps = numpy.empty((3, rampSize), dtype=numpy.uint16)
        success = xf86vm.XF86VidModeGetGammaRamp(
            xDisplay, screenID, rampSize,
            origramps[0, :].ctypes,
            origramps[1, :].ctypes,
            origramps[2, :].ctypes)
        if not success:
            raise AssertionError('XF86VidModeGetGammaRamp failed')
        origramps = origramps/65535.0  # rescale to 0:1

    elif _TravisTesting:
        logging.warn("It looks like we're running in the Travis-CI testing "
                     "environment. Hardware gamma table cannot be retrieved")
        origramps = None

    return origramps
Ejemplo n.º 55
0
def _bestDriver(devNames, devIDs):
    """Find ASIO or Windows sound drivers
    """
    preferredDrivers = prefs.general['audioDriver']
    outputID=None
    audioDriver=None
    for prefDriver in preferredDrivers:
        if prefDriver.lower()=='directsound':
            prefDriver = 'Primary Sound'
        #look for that driver in available devices
        for devN, devString in enumerate(devNames):
            try:
                if prefDriver.encode('utf-8') in devString.encode('utf-8'):
                    audioDriver=devString
                    outputID=devIDs[devN]
                    return audioDriver, outputID #we found an asio driver don'w look for others
            except UnicodeDecodeError, UnicodeEncodeError:
                logging.warn('find best sound driver - could not interpret unicode in driver name')
Ejemplo n.º 56
0
def _bestDriver(devNames, devIDs):
    """Find ASIO or Windows sound drivers
    """
    preferredDrivers = prefs.general["audioDriver"]
    outputID = None
    audioDriver = None
    for prefDriver in preferredDrivers:
        if prefDriver.lower() == "directsound":
            prefDriver = "Primary Sound"
        # look for that driver in available devices
        for devN, devString in enumerate(devNames):
            try:
                if prefDriver.encode("utf-8") in devString.encode("utf-8"):
                    audioDriver = devString
                    outputID = devIDs[devN]
                    return audioDriver, outputID  # we found an asio driver don'w look for others
            except UnicodeDecodeError, UnicodeEncodeError:
                logging.warn("find best sound driver - could not interpret unicode in driver name")
Ejemplo n.º 57
0
def getGammaRampSize(screenID, xDisplay=None):
    """Returns the size of each channel of the gamma ramp."""

    if sys.platform == 'win32':

        # windows documentation (for SetDeviceGammaRamp) seems to indicate that
        # the LUT size is always 256
        rampSize = 256

    elif sys.platform == 'darwin':

        rampSize = carbon.CGDisplayGammaTableCapacity(screenID)

    elif sys.platform.startswith('linux') and not _TravisTesting:

        rampSize = ctypes.c_int()

        success = xf86vm.XF86VidModeGetGammaRampSize(
            xDisplay,
            screenID,
            ctypes.byref(rampSize)
        )

        assert success, 'XF86VidModeGetGammaRampSize failed'

        rampSize = rampSize.value

    else:

        assert _TravisTesting

        rampSize = 256

    if rampSize == 0:

        logging.warn(
            "The size of the gamma ramp was reported as 0. This can " +
            "mean that gamma settings have no effect. Proceeding with " +
            "a default gamma ramp size."
        )

        rampSize = 256

    return rampSize
Ejemplo n.º 58
0
    def load(self, proj_path=None):
        """Load the project from a json-format file
        """
        if projPath is None:
            projPath = self.project_path
        if not os.path.isfile(proj_path):
            self.session = remote.Session()

        # todo: handle the case that the path doesn't (yet) exist
        with open(projPath, 'r') as f:
            d = json.load(f)
        if not self.root_path:
            self.root_path = d['root_path']
        elif self.root_path != d['root_path']:
            logging.warn("The Project was given a directory that does not "
                         "match the previous stored location. "
                         "Using new location.")
        self.session = remote.Session(token=d['session']['token'])
        self.index = d['index']
Ejemplo n.º 59
0
def _bestDriver(devNames, devIDs):
    """Find ASIO or Windows sound drivers
    """
    preferredDrivers = prefs.general['audioDriver']
    outputID=None
    audioDriver=None
    for prefDriver in preferredDrivers:
        if prefDriver.lower()=='directsound':
            prefDriver = 'Primary Sound'
        #look for that driver in available devices
        for devN, devString in enumerate(devNames):
            try:
                if prefDriver.encode('utf-8') in devString.encode('utf-8'):
                    audioDriver=devString
                    outputID=devIDs[devN]
                    return audioDriver, outputID #we found an asio driver don'w look for others
            except (UnicodeDecodeError, UnicodeEncodeError):
                logging.warn('find best sound driver - could not interpret unicode in driver name')
    else:
        return None, None
Ejemplo n.º 60
0
def initPygame(rate=22050, bits=16, stereo=True, buffer=1024):
    """If you need a specific format for sounds you need to run this init
    function. Run this *before creating your visual.Window*.

    The format cannot be changed once initialised or once a Window has been created.

    If a Sound object is created before this function is run it will be
    executed with default format (signed 16bit stereo at 22KHz).

    For more details see pygame help page for the mixer.
    """
    global Sound, audioDriver
    Sound = SoundPygame
    audioDriver='n/a'
    if stereo==True: stereoChans=2
    else:   stereoChans=0
    if bits==16: bits=-16 #for pygame bits are signed for 16bit, signified by the minus
    mixer.init(rate, bits, stereoChans, buffer) #defaults: 22050Hz, 16bit, stereo,
    sndarray.use_arraytype("numpy")
    setRate, setBits, setStereo = mixer.get_init()
    if setRate!=rate:
        logging.warn('Requested sound sample rate was not poossible')
    if setBits!=bits:
        logging.warn('Requested sound depth (bits) was not possible')
    if setStereo!=2 and stereo==True:
        logging.warn('Requested stereo setting was not possible')