Exemple #1
0
    def record(self, sec, file='', block=True):
        """Capture sound input for duration <sec>, save to a file.

        Return the path/name to the new file. Uses onset time (epoch) as
        a meaningful identifier for filename and log.
        """
        while self.recorder.running:
            pass
        self.duration = float(sec)
        self.onset = core.getTime() # note: report onset time in log, and use in filename
        logging.data('%s: Record: onset %.3f, capture %.3fs' %
                     (self.loggingId, self.onset, self.duration) )
        if not file:
            onsettime = '-%.3f' % self.onset
            self.savedFile = onsettime.join(os.path.splitext(self.wavOutFilename))
        else:
            self.savedFile = os.path.abspath(file).strip('.wav') + '.wav'

        t0 = core.getTime()
        self.recorder.run(self.savedFile, self.duration, self.sampletype)
        self.rate = sound.pyoSndServer.getSamplingRate()

        if block:
            core.wait(self.duration - .0008) # .0008 fudge factor for better reporting
                # actual timing is done by Clean_objects
            logging.exp('%s: Record: stop. %.3f, capture %.3fs (est)' %
                     (self.loggingId, core.getTime(), core.getTime() - t0) )
        else:
            logging.exp('%s: Record: return immediately, no blocking' %
                     (self.loggingId) )

        return self.savedFile
Exemple #2
0
def waitKeys(maxWait=float('inf'), keyList=None, timeStamped=False):
    """
    Same as `~psychopy.event.getKeys`, but halts everything (including drawing) while awaiting
    input from keyboard. Implicitly clears keyboard, so any preceding keypresses will be lost.

    :Parameters:
        maxWait : any numeric value.
            Maximum number of seconds period and which keys to wait for.
            Default is float('inf') which simply waits forever.

    Returns None if times out.
    """

    #NB pygame.event does have a wait() function that will
    #do this and maybe leave more cpu idle time?
    key = None
    clearEvents('keyboard')  # So that we only take presses from here onwards.

    # Check for keypresses until maxWait is exceeded
    timer = psychopy.core.Clock()
    while key == None and timer.getTime() < maxWait:
        # Pump events on pyglet windows if they exist
        if havePyglet:
            wins = pyglet.window.get_platform().get_default_display().get_windows()
            for win in wins: win.dispatch_events()

        # Get keypresses and return if anything is pressed
        keys = getKeys(keyList=keyList, timeStamped=timeStamped)
        if len(keys):
            return keys

    # If maxWait is exceeded (exits while-loop), return None
    logging.data("No keypress (maxWait exceeded)")
    return None
Exemple #3
0
    def record(self, sec, block=True):
        """Capture sound input for duration <sec>, save to a file.
        
        Return the path/name to the new file. Uses onset time (epoch) as
        a meaningful identifier for filename and log.
        """
        RECORD_SECONDS = float(sec)
        self.onset = time.time() # note: report onset time in log, and use in filename
        logging.data('%s: Record: onset %.3f, capture %.3fs' %
                     (self.loggingId, self.onset, RECORD_SECONDS) )
        
        self.savedFile = self.wavOutFilename.replace(ONSET_TIME_HERE, '-%.3f' % self.onset)
        inputter = Input(chnl=0, mul=1) # chnl=[0,1] for stereo input
        t0 = time.time()
        # launch the recording, saving to file:
        recorder = Record(inputter,
                        self.savedFile,
                        chnls=2,
                        fileformat=0, # .wav format
                        sampletype=0,
                        buffering=4) # 4 is default
        # launch recording, block as needed, and clean up:
        clean = Clean_objects(RECORD_SECONDS, recorder) # set up to stop recording
        clean.start() # the timer starts now, ends automatically whether block or not
        if block:
            time.sleep(RECORD_SECONDS - 0.0008) # Clean_objects() set-up takes ~0.0008s, for me
            logging.exp('%s: Record: stop. %.3f, capture %.3fs (est)' %
                     (self.loggingId, time.time(), time.time() - t0) )
        else:
            logging.exp('%s: Record: return immediately, no blocking' %
                     (self.loggingId) )
        
        self.duration = RECORD_SECONDS # used in playback()

        return self.savedFile # filename, or None
Exemple #4
0
def _onPygletKey(symbol, modifiers, emulated=False):
    """handler for on_key_press pyglet events, or call directly to emulate a key press

    Appends a tuple with (keyname, timepressed) into the global _keyBuffer. The
    _keyBuffer can then be accessed as normal using event.getKeys(), .waitKeys(),
    clearBuffer(), etc.

    J Gray 2012: Emulated means add a key (symbol) to the buffer virtually.
    This is useful for fMRI_launchScan, and for unit testing (in testTheApp)
    Logging distinguished EmulatedKey events from real Keypress events.
    For emulation, the key added to the buffer is unicode(symbol), instead of
    pyglet.window.key.symbol_string(symbol)

    S Mathot 2012: Implement fallback to _onPygletText
    """

    global useText
    keyTime=psychopy.core.getTime() #capture when the key was pressed
    if emulated:
        thisKey = unicode(symbol)
        keySource = 'EmulatedKey'
    else:
        thisKey = pyglet.window.key.symbol_string(symbol).lower() #convert symbol into key string
        #convert pyglet symbols to pygame forms ( '_1'='1', 'NUM_1'='[1]')
        # 'user_key' indicates that Pyglet has been unable to make sense out of
        # the keypress. In that case, we fall back to _onPygletText to handle
        # the input.
        if 'user_key' in thisKey:
            useText = True
            return
        useText = False
        thisKey = thisKey.lstrip('_').lstrip('NUM_')
        keySource = 'Keypress'
    _keyBuffer.append( (thisKey,keyTime) ) # tuple
    logging.data("%s: %s" % (keySource, thisKey))
Exemple #5
0
    def _record(self, sec, filename="", block=True, log=True):
        while self.recorder.running:
            pass
        self.duration = float(sec)
        self.onset = core.getTime()  # for duration estimation, high precision
        self.fileOnset = core.getAbsTime()  # for log and filename, 1 sec precision
        ms = "%.3f" % (core.getTime() - int(core.getTime()))
        if log and self.autoLog:
            logging.data("%s: Record: onset %d, capture %.3fs" % (self.loggingId, self.fileOnset, self.duration))
        if not filename:
            onsettime = "-%d" % self.fileOnset + ms[1:]
            self.savedFile = onsettime.join(os.path.splitext(self.wavOutFilename))
        else:
            self.savedFile = os.path.abspath(filename).strip(".wav") + ".wav"

        t0 = core.getTime()
        self.recorder.run(self.savedFile, self.duration, **self.options)

        self.rate = sound.pyoSndServer.getSamplingRate()
        if block:
            core.wait(self.duration, 0)
            if log and self.autoLog:
                logging.exp(
                    "%s: Record: stop. %.3f, capture %.3fs (est)"
                    % (self.loggingId, core.getTime(), core.getTime() - t0)
                )
            while self.recorder.running:
                core.wait(0.001, 0)
        else:
            if log and self.autoLog:
                logging.exp("%s: Record: return immediately, no blocking" % (self.loggingId))

        return self.savedFile
Exemple #6
0
def _onGLFWKey(*args, **kwargs):
    """Callback for key/character events for the GLFW backend.

    :return:
    """
    keyTime = psychopy.core.getTime()  # get timestamp

    # TODO - support for key emulation
    win_ptr, key, scancode, action, modifiers = args
    global useText
    
    if key == glfw.KEY_UNKNOWN:
        useText = True
        return
    useText = False

    # get the printable name, always make lowercase
    key_name = glfw.get_key_name(key, scancode)

    # if there is no localized key name or space
    if key_name is None or key_name == ' ':
        try:
            key_name = _glfw_keycodes_[key]
        except KeyError:
            pass
    else:
        key_name = key_name.lower()

    # TODO - modifier integration
    keySource = 'Keypress'
    _keyBuffer.append((key_name, modifiers, keyTime))  # tuple
    logging.data("%s: %s" % (keySource, key_name))
Exemple #7
0
def _onPygletText(text, emulated=False):
    """handler for on_text pyglet events, or call directly to emulate a text
    event.

    S Mathot 2012: This function only acts when the key that is pressed
    corresponds to a non-ASCII text character (Greek, Arabic, Hebrew, etc.).
    In that case the symbol that is passed to _onPygletKey() is translated
    into a useless 'user_key()' string. If this happens, _onPygletText takes
    over the role of capturing the key. Unfortunately, _onPygletText()
    cannot solely handle all input, because it does not respond to spacebar
    presses, etc.
    """

    global useText
    if not useText:  # _onPygletKey has handled the input
        return
    # This is needed because sometimes the execution
    # sequence is messed up (somehow)
    useText = False
    # capture when the key was pressed:
    keyTime = psychopy.core.getTime()
    if emulated:
        keySource = 'EmulatedKey'
    else:
        keySource = 'KeyPress'
    _keyBuffer.append((text.lower(), lastModifiers, keyTime))
    logging.data("%s: %s" % (keySource, text))
    def _record(self, sec, filename='', block=True):
        while self.recorder.running:
            pass
        self.duration = float(sec)
        self.onset = core.getTime()  # for duration estimation, high precision
        self.fileOnset = core.getAbsTime()  # for log and filename, 1 sec precision
        logging.data('%s: Record: onset %d, capture %.3fs' %
                     (self.loggingId, self.fileOnset, self.duration) )
        if not file:
            onsettime = '-%d' % self.fileOnset
            self.savedFile = onsettime.join(os.path.splitext(self.wavOutFilename))
        else:
            self.savedFile = os.path.abspath(filename).strip('.wav') + '.wav'

        t0 = core.getTime()
        self.recorder.run(self.savedFile, self.duration, **self.options)

        self.rate = sound.pyoSndServer.getSamplingRate()
        if block:
            core.wait(self.duration, 0)
            logging.exp('%s: Record: stop. %.3f, capture %.3fs (est)' %
                     (self.loggingId, core.getTime(), core.getTime() - t0) )
            while self.recorder.running:
                core.wait(.001, 0)
        else:
            logging.exp('%s: Record: return immediately, no blocking' %
                     (self.loggingId) )

        return self.savedFile
Exemple #9
0
def _onGLFWMouseScroll(*args, **kwargs):
    """Callback for mouse scrolling events. For most computer mice with scroll
    wheels, only the vertical (Y-offset) is relevant.

    """
    window_ptr, x_offset, y_offset = args
    global mouseWheelRel
    mouseWheelRel = mouseWheelRel + numpy.array([x_offset, y_offset])
    msg = "Mouse: wheel shift=(%i,%i)"
    logging.data(msg % (x_offset, y_offset))
Exemple #10
0
def _onPygletMouseRelease(x,y, button, modifiers):
    global mouseButtons
    if button == pyglet.window.mouse.LEFT:
        mouseButtons[0]=0
        label='Left'
    if button == pyglet.window.mouse.MIDDLE:
        mouseButtons[1]=0
        label='Middle'
    if button == pyglet.window.mouse.RIGHT:
        mouseButtons[2]=0
        label='Right'
    logging.data("Mouse: %s button up, pos=(%i,%i)" %(label, x,y))
Exemple #11
0
def _onPygletKey(symbol, modifiers, emulated=False):
    """handler for on_key_press pyglet events; call directly to emulate a
    key press

    Appends a tuple with (keyname, timepressed) into the global _keyBuffer.
    The _keyBuffer can then be accessed as normal using event.getKeys(),
    .waitKeys(), clearBuffer(), etc.

    J Gray 2012: Emulated means add a key (symbol) to the buffer virtually.
    This is useful for fMRI_launchScan, and for unit testing (in testTheApp)
    Logging distinguishes EmulatedKey events from real Keypress events.
    For emulation, the key added to the buffer is unicode(symbol), instead of
    pyglet.window.key.symbol_string(symbol).

    S Mathot 2012: Implement fallback to _onPygletText

    5AM Solutions 2016: Add the keyboard modifier flags to the key buffer.

    M Cutone 2018: Added GLFW backend support.

    """
    global useText, lastModifiers

    keyTime = psychopy.core.getTime()  # capture when the key was pressed
    if emulated:
        if not isinstance(modifiers, int):
            msg = 'Modifiers must be passed as an integer value.'
            raise ValueError(msg)

        thisKey = str(symbol)
        keySource = 'EmulatedKey'
    else:
        thisKey = pyglet.window.key.symbol_string(
            symbol).lower()  # convert symbol into key string
        # convert pyglet symbols to pygame forms ( '_1'='1', 'NUM_1'='[1]')
        # 'user_key' indicates that Pyglet has been unable to make sense
        # out of the keypress. In that case, we fall back to _onPygletText
        # to handle the input.
        if 'user_key' in thisKey:
            useText = True
            lastModifiers = modifiers
            return
        useText = False
        thisKey = thisKey.lstrip('_').lstrip('NUM_')
        # Pyglet 1.3.0 returns 'enter' when Return key (0xFF0D) is pressed 
        # in Windows Python3. So we have to replace 'enter' with 'return'.
        if thisKey == 'enter':
            thisKey = 'return'
        keySource = 'Keypress'
    _keyBuffer.append((thisKey, modifiers, keyTime))  # tuple
    logging.data("%s: %s" % (keySource, thisKey))
    _process_global_event_key(thisKey, modifiers)
Exemple #12
0
    def stop(self):
        """Interrupt a recording that is in progress; close & keep the file.

        Ends the recording before the duration that was initially specified. The
        same file name is retained, with the same onset time but a shorter duration.

        The same recording cannot be resumed after a stop (it is not a pause),
        but you can start a new one.
        """
        if not self.recorder.running:
            logging.exp('%s: Stop requested, but no record() in progress' % self.loggingId )
            return
        self.duration = core.getTime() - self.onset  # new shorter duration
        self.recorder.stop()
        logging.data('%s: Record stopped early, new duration %.3fs' % (self.loggingId, self.duration))
Exemple #13
0
def _onPygletMousePress(x,y, button, modifiers):
    global mouseButtons, mouseClick, mouseTimes
    if button == pyglet.window.mouse.LEFT:
        mouseButtons[0]=1
        mouseTimes[0]= psychopy.clock.getTime()-mouseClick[0].getLastResetTime()
        label='Left'
    if button == pyglet.window.mouse.MIDDLE:
        mouseButtons[1]=1
        mouseTimes[1]= psychopy.clock.getTime()-mouseClick[1].getLastResetTime()
        label='Middle'
    if button == pyglet.window.mouse.RIGHT:
        mouseButtons[2]=1
        mouseTimes[2]= psychopy.clock.getTime()-mouseClick[2].getLastResetTime()
        label='Right'
    logging.data("Mouse: %s button down, pos=(%i,%i)" %(label, x,y))
Exemple #14
0
def _onPygletMouseRelease(x, y, button, modifiers, emulated=False):
    global mouseButtons
    if emulated:
        label = 'Emulated'
    else:
        label = ''
    if button & LEFT:
        mouseButtons[0] = 0
        label += ' Left'
    if button & MIDDLE:
        mouseButtons[1] = 0
        label += ' Middle'
    if button & RIGHT:
        mouseButtons[2] = 0
        label += ' Right'
    logging.data("Mouse: %s button up, pos=(%i,%i)" % (label, x, y))
Exemple #15
0
def _onGLFWText(*args, **kwargs):
    """Handle unicode character events if _onGLFWKey() cannot.

    :return:
    """
    keyTime = psychopy.core.getTime()  # get timestamp



    # TODO - support for key emulation
    win_ptr, codepoint, modifiers = args
    # win = glfw.get_window_user_pointer(win_ptr)
    text = chr(codepoint)  # convert to unicode character (Python 3.0)
    global useText
    if not useText:  # _onPygletKey has handled the input
        return
    keySource = 'KeyPress'
    _keyBuffer.append((text, keyTime))
    logging.data("%s: %s" % (keySource, text))
Exemple #16
0
    def _record(self, sec, filename='', block=True, log=True):
        filename = pathToString(filename)
        while self.recorder.running:
            pass
        self.duration = float(sec)
        # for duration estimation, high precision:
        self.onset = core.getTime()
        # use time for unique log and filename, 1 sec precision
        self.fileOnset = core.getAbsTime()
        ms = "%.3f" % (core.getTime() - int(core.getTime()))
        if log and self.autoLog:
            msg = '%s: Record: onset %d, capture %.3fs'
            logging.data(msg % (self.loggingId, self.fileOnset,
                                self.duration))
        if not filename:
            onsettime = '-%d' % self.fileOnset + ms[1:]
            self.savedFile = onsettime.join(
                os.path.splitext(self.wavOutFilename))
        else:
            self.savedFile = os.path.abspath(filename)
            if not self.savedFile.endswith('.wav'):
                self.savedFile += '.wav'

        t0 = core.getTime()
        self.recorder.run(self.savedFile, self.duration, **self.options)

        self.rate = sound.backend.pyoSndServer.getSamplingRate()
        if block:
            core.wait(self.duration, 0)
            if log and self.autoLog:
                msg = '%s: Record: stop. %.3f, capture %.3fs (est)'
                logging.exp(msg % (self.loggingId, core.getTime(),
                                   core.getTime() - t0))
            while self.recorder.running:
                core.wait(.001, 0)
        else:
            if log and self.autoLog:
                msg = '%s: Record: return immediately, no blocking'
                logging.exp(msg % (self.loggingId))

        return self.savedFile
Exemple #17
0
def _onPygletMousePress(x,y, button, modifiers, emulated=False):
    """button left=1, middle=2, right=4;
    """
    global mouseButtons, mouseClick, mouseTimes
    if emulated:
        label = 'Emulated'
    else:
        label = ''
    if button & LEFT:
        mouseButtons[0]=1
        mouseTimes[0]= psychopy.clock.getTime()-mouseClick[0].getLastResetTime()
        label += ' Left'
    if button & MIDDLE:
        mouseButtons[1]=1
        mouseTimes[1]= psychopy.clock.getTime()-mouseClick[1].getLastResetTime()
        label += ' Middle'
    if button & RIGHT:
        mouseButtons[2]=1
        mouseTimes[2]= psychopy.clock.getTime()-mouseClick[2].getLastResetTime()
        label += ' Right'
    logging.data("Mouse: %s button down, pos=(%i,%i)" %(label.strip(), x,y))
Exemple #18
0
# %% RENDER_LOOP

# Create Counters
i = 0
# give the system time to settle
core.wait(1)

# wait for scanner trigger
triggerText.draw()
myWin.flip()
event.waitKeys(keyList=['5'], timeStamped=False)

# reset clocks
clock.reset()
logging.data('StartOfRun' + unicode(expInfo['run']))

while clock.getTime() < totalTime:

    keyMask = conditions[i, 0]

    # blank
    if conditions[i, 1] == 0:
        # set texture
        visTexture = wedge
        # set timing for the opacity
        visOpa = cycTransp

    # horibar
    elif conditions[i, 1] == 1:
        # set stimulus position
    def begin_trial(self):
        logging.debug(u'Entered SentenceTrial().begin_trial()')

        self.text_left.text = ''
        self.text_right.text = ''

        logging.info(u'{}: Reset text'.format(self.text_left.name))
        logging.info(u'{}: Reset text'.format(self.text_right.name))

        self.show_blank(.5 * SPEED_MULTIPLIER)
        fixation_length = (1 + 1 * random()) * SPEED_MULTIPLIER
        self.show_fixation(fixation_length)

        sentence_correct = True

        prev_pos = ''
        prev_resp = ''
        logging.exp(u'trial_clock: Reset time')
        self.trial_clock.reset()
        for pair in self.trial:
            self.show_fixation(0.2 * SPEED_MULTIPLIER)

            target_pos = self.show_pair(pair)

            logging.exp(u'pair_clock: Reset time')
            self.pair_clock.reset()

            acc, response_time, response = self.get_response(target_pos)
            self.clear_pair()

            self.trial.addData('target_pos', target_pos)
            if target_pos == 0:
                self.trial.addData('target_pos.verbose', 'L')
            else:
                self.trial.addData('target_pos.verbose', 'R')

            self.trial.addData('resp', response)
            if response == 0:
                self.trial.addData('resp.verbose', 'L')
            else:
                self.trial.addData('resp.verbose', 'R')

            self.trial.addData('resp.RT',
                               '{:.2f}'.format(response_time * 1000))
            self.trial.addData('resp.acc', acc)

            self.trial.addData('prev.pos', prev_pos)
            self.trial.addData('prev.resp', prev_resp)

            if self.autorun:
                self.trial.addData(
                    'TRIAL_AUTORUN',
                    u'EXPERIMENT IN AUTORUN MODE DO NOT USE DATA')

            prev_pos = target_pos
            prev_resp = response

            self.parent.experiment.nextEntry()

            if acc == 0:
                logging.exp(u'Incorrect sentence path chosen')
                sentence_correct = False
                break
        block_time = self.trial_clock.getTime()

        self.show_feedback(sentence_correct)
        self.experiment.loopEnded(self.trial)

        if sentence_correct:
            logging.info(u'Sentence completed accurately.')
            logging.data(u'Block completion time: {}'.format(block_time))
            logging.data(u'Block accuracy: {}'.format(1))
            return 1, block_time, fixation_length
        else:
            logging.info(u'Sentence was not completed accurately.')
            logging.data(u'Block completion time: {}'.format(block_time))
            logging.data(u'Block accuracy: {}'.format(0))
            return 0, block_time, fixation_length
    def get_response(self, target_pos):
        logging.exp(u'Waiting for response...')

        if self.autorun:
            logging.exp(u'Autorun active. Sending automatic response...')
            auto_response_time = 0.5 + random()
            if randint(0, 100) < 98:
                return 1, auto_response_time, target_pos
            else:
                return 0, auto_response_time, int(not target_pos)

        if self.use_srbox:
            response, response_time = self.srbox.waitKeys(
                keyList=[1, 5], timeStamped=self.pair_clock)
            response = response[0]
        else:
            response, response_time = event.waitKeys(
                keyList=['c', 'm'], timeStamped=self.pair_clock)[0]
        logging.exp(u'Key presses received')
        # response_time = self.pair_clock.getTime()

        if response in ('c', 1):
            response = 0
        elif response in ('m', 5):
            response = 1

        logging.exp(u'Kepress position: {}'.format(response))

        if response == target_pos:
            logging.info(u'Kepress does match target position.')
            logging.data(u'Response: {}'.format(response))
            logging.data(u'Acc: {}'.format(1))
            logging.data(u'Response time: {}'.format(response_time))
            return 1, response_time, response
        else:
            logging.info(u'Kepress does match target position.')
            logging.data(u'Response: {}'.format(response))
            logging.data(u'Acc: {}'.format(0))
            logging.data(u'Response time: {}'.format(response_time))
            return 0, response_time, response
Exemple #21
0
def _onPygletMouseWheel(x, y, scroll_x, scroll_y):
    global mouseWheelRel
    mouseWheelRel = mouseWheelRel + numpy.array([scroll_x, scroll_y])
    msg = "Mouse: wheel shift=(%i,%i), pos=(%i,%i)"
    logging.data(msg % (scroll_x, scroll_y, x, y))
Exemple #22
0
"""
globalClock = core.Clock(
)  #if this isn't provided the log times will reflect secs since python started
logging.setDefaultClock(globalClock)  #use this for

logging.console.setLevel(
    logging.DEBUG)  #set the console to receive nearly all messges
logDat = logging.LogFile(
    'logLastRun.log',
    filemode='w',  #if you set this to 'a' it will append instead of overwriting
    level=logging.WARNING
)  #errors, data and warnings will be sent to this logfile

#the following will go to any files with the appropriate minimum level set
logging.info('Something fairly unimportant')
logging.data('Something about our data. Data is likely very important!')
logging.warning(
    'Handy while building your experiment - highlights possible flaws in code/design'
)
logging.error(
    "You might have done something that PsychoPy can't handle! But hopefully this gives you some idea what."
)

#some things should be logged timestamped on the next video frame
#For instance the time of a stimulus appearing is related to the flip:
win = visual.Window([400, 400])
for n in range(5):
    win.logOnFlip('frame %i occured' % n, level=logging.EXP)
    if n in [2, 4]:
        win.logOnFlip('an even frame occured', level=logging.EXP)
    win.flip()
Exemple #23
0
def waitKeys(maxWait=float('inf'),
             keyList=None,
             modifiers=False,
             timeStamped=False,
             clearEvents=True):
    """Same as `~psychopy.event.getKeys`, but halts everything
    (including drawing) while awaiting input from keyboard.

    :Parameters:
        maxWait : any numeric value.
            Maximum number of seconds period and which keys to wait for.
            Default is float('inf') which simply waits forever.
        keyList : **None** or []
            Allows the user to specify a set of keys to check for.
            Only keypresses from this set of keys will be removed from
            the keyboard buffer. If the keyList is `None`, all keys will be
            checked and the key buffer will be cleared completely.
            NB, pygame doesn't return timestamps (they are always 0)
        modifiers : **False** or True
            If True will return a list of tuples instead of a list of
            keynames. Each tuple has (keyname, modifiers). The modifiers
            are a dict of keyboard modifier flags keyed by the modifier
            name (eg. 'shift', 'ctrl').
        timeStamped : **False**, True, or `Clock`
            If True will return a list of tuples instead of a list of
            keynames. Each tuple has (keyname, time). If a `core.Clock`
            is given then the time will be relative to the `Clock`'s last
            reset.
        clearEvents : **True** or False
            Whether to clear the keyboard event buffer (and discard preceding
            keypresses) before starting to monitor for new keypresses.

    Returns None if times out.

    """
    if clearEvents:
        # Only consider keypresses from here onwards.
        # We need to invoke clearEvents(), but our keyword argument is
        # also called clearEvents. We can work around this conflict by
        # accessing the global scope explicitly.
        globals()['clearEvents']('keyboard')

    # Check for keypresses until maxWait is exceeded
    #
    # NB pygame.event does have a wait() function that will
    # do this and maybe leave more cpu idle time?

    timer = psychopy.core.Clock()
    got_keypress = False

    while not got_keypress and timer.getTime() < maxWait:
        # Pump events on pyglet windows if they exist.
        if havePyglet:
            for win in _default_display_.get_windows():
                win.dispatch_events()

        # Get keypresses and return if anything is pressed.
        keys = getKeys(keyList=keyList,
                       modifiers=modifiers,
                       timeStamped=timeStamped)
        if keys:
            got_keypress = True

    if got_keypress:
        return keys
    else:
        logging.data('No keypress (maxWait exceeded)')
        return None
Exemple #24
0
def waitKeys(maxWait = None, keyList=None):
    """
    Halts everything (including drawing) while awaiting
    input from keyboard. Then returns *list* of keys pressed. Implicitly clears
    keyboard, so any preceding keypresses will be lost.

    Optional arguments specify maximum wait period and which keys to wait for.

    Returns None if times out.
    """

    #NB pygame.event does have a wait() function that will
    #do this and maybe leave more cpu idle time?
    key=None
    clearEvents('keyboard')#so that we only take presses from here onwards.
    if maxWait!=None and keyList!=None:
        #check keylist AND timer
        timer = psychopy.core.Clock()
        while key==None and timer.getTime()<maxWait:
            if havePyglet:
                wins = pyglet.window.get_platform().get_default_display().get_windows()
                for win in wins: win.dispatch_events()#pump events on pyglet windows
            keys = getKeys()
            #check if we got a key in list
            if len(keys)>0 and (keys[0] in keyList):
                key = keys[0]

    elif keyList!=None:
        #check the keyList each time there's a press
        while key==None:
            if havePyglet:
                wins = pyglet.window.get_platform().get_default_display().get_windows()
                for win in wins: win.dispatch_events()#pump events on pyglet windows
            keys = getKeys()
            #check if we got a key in list
            if len(keys)>0 and (keys[0] in keyList):
                key = keys[0]

    elif maxWait!=None:
        #onyl wait for the maxWait
        timer = psychopy.core.Clock()
        while key==None and timer.getTime()<maxWait:
            if havePyglet:
                wins = pyglet.window.get_platform().get_default_display().get_windows()
                for win in wins: win.dispatch_events()#pump events on pyglet windows
            keys = getKeys()
            #check if we got a key in list
            if len(keys)>0:
                key = keys[0]

    else: #simply take the first key we get
        while key==None:
            if havePyglet:
                wins = pyglet.window.get_platform().get_default_display().get_windows()
                for win in wins: win.dispatch_events()#pump events on pyglet windows
            keys = getKeys()
            #check if we got a key in list
            if len(keys)>0:
                key = keys[0]

    #after the wait period or received a valid keypress
    if key:
        logging.data("Key pressed: %s" %key)
        return [key]#need to convert back to a list
    else:
        return None #no keypress in period
def main_block_design(win, globalClock):

    ############## Stimuli preparation ##############

    # Fixation cross preparation
    fixation = visual.Circle(win,
                             radius=10,
                             lineColor='white',
                             fillColor='white',
                             units='pix')

    subject_instructions = visual.TextStim(win,
                                           pos=[0, 0],
                                           text='',
                                           alignVert='center',
                                           wrapWidth=1.5)

    tennis_sound = sound.Sound(Path_in_sounds + sounds_filename_tennis)
    house_sound = sound.Sound(Path_in_sounds + sounds_filename_house)
    faces_sound = sound.Sound(Path_in_sounds + sounds_filename_faces)

    tennis = [string_tennis, tennis_sound]
    house = [string_house, house_sound]
    faces = [string_faces, faces_sound]

    ############## Definitions/Functions ##############

    ## handle Rkey presses each frame
    def escapeCondition():
        for key in event.getKeys():
            if key in ['escape', 'q']:
                return False
        return True

    ## Display just fixation
    def displayFixation(win, fixation_time=2, break_flag=True):

        timer_fixation = core.CountdownTimer(fixation_time)
        while (timer_fixation.getTime() > 0 and break_flag == True):

            fixation.draw()
            win.flip()  # Update screen
            break_flag = escapeCondition()
        return break_flag

    ## Display just a message
    def displayInstruction(win,
                           string_instruction,
                           sound,
                           string_time=2,
                           break_flag=True):

        timer_string = core.CountdownTimer(string_time)
        sound.play()
        while (timer_string.getTime() > 0 and break_flag == True):

            subject_instructions.text = string_instruction
            subject_instructions.draw()
            win.flip()  # Update screen
            break_flag = escapeCondition()
        return break_flag

    ## Initialise experiment: select trails and log them
    block_order = np.random.permutation([tennis, house, faces] * blocks_number)
    logging.data("Trails order:")
    logging.data(block_order)

    ############## Exp. begin ##############

    # Display first set of instructions and wait
    message1 = visual.TextStim(win,
                               pos=[0, 0],
                               text=init_mess_1,
                               alignVert='center',
                               wrapWidth=1.5)
    message1.size = .5
    message1.draw()
    win.flip()
    event.waitKeys()  #pause until there's a keypress

    # Waiting for the scanner
    if SCANNER:
        message3 = visual.TextStim(win,
                                   pos=[0, 0.25],
                                   text=scanner_message,
                                   alignVert='center',
                                   wrapWidth=1.5)
        message3.size = .5
        message3.draw()
        win.flip()
        while 1:
            allKeys = event.getKeys()
            if MR_settings['sync'] in allKeys:
                break

    # Start run
    experiment_begin = dt.now()

    inizio = globalClock.getTime()
    logging.data('Begin of the experiment (trigger) at: %.6f' % (inizio))

    # Run experiment a 'run' at the time
    for i_block in block_order:

        i_block_string = i_block[0]
        i_block_sound = i_block[1]

        logging.data('*** Run: ' + str(i_block_string) + ' ***')

        # Fixation
        if displayFixation(win, fixation_time=inter_blocks_length) == False:
            break

        # Show condition "tennis" or "house"
        if displayInstruction(win,
                              string_instruction=i_block_string,
                              string_time=block_length,
                              sound=i_block_sound) == False:
            break

    # Display final fixation
    if displayFixation(win, fixation_time=inter_blocks_length) == False: return

    # Display final message
    message4 = visual.TextStim(win,
                               pos=[0, 0.25],
                               text=final_message,
                               alignVert='center',
                               wrapWidth=1.5)
    message4.size = .5
    message4.draw()
    win.flip()
    core.wait(3)

    logging.data('***** End *****\n')

    logging.data('Total time spent: %s' % (dt.now() - experiment_begin))
    logging.data('Every frame duration saved in %s' %
                 (path_out + Frames_durations_name))

    return
#create a window to draw in
myWin =visual.Window((600,600), allowGUI=False,
    bitsMode=None, units='norm', winType='pyglet')

#INITIALISE SOME STIMULI
dotPatch =visual.DotStim(myWin, rgb=(1.0,1.0,1.0), dir=270,
    nDots=100, fieldShape='circle', fieldPos=(0.0,0.0),fieldSize=1,
    dotLife=5, #number of frames for each dot to be drawn
    signalDots='same', #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'
    speed=0.01, coherence=0.9)
message =visual.TextStim(myWin,text='Hit Q to quit',
    pos=(0,-0.5))
trialClock =core.Clock()
myWin.setRecordFrameIntervals()
n=0
while True:#quits after 20 secs
    n+=1
    dotPatch.draw()
    message.draw()
    myWin.flip()#redraw the buffer
    for n in range(10):
        logging.info('%i info' %n)
    #handle key presses each frame
    for key in event.getKeys():
        if key in ['escape','q']:
            logging.data('final fps = %.3f' % myWin.fps())
            myWin.close()
            core.quit()
    event.clearEvents()#keep the event buffer from overflowing
"""
sentencecomp.py - code to run the sentence comprehension task for the reading remediation study
"""

from psychopy import visual, core, event, logging,gui
import numpy as N
import pickle
import datetime
import sys
import os
import inspect
import hashlib
from socket import gethostname

from exptutils import *

# study-specific routines

def load_sentences(filename):
    f=open(filename)
    ll=f.readlines()
    f.close()
    s={}
    s['sentence']=[]
    s['cond']=[]
    s['onset']=[]
    for l in ll:
        l_s=l.split('\t')
        #print l_s
        s['sentence'].append(' '.join(l_s[2:]).strip('\n'))
Exemple #28
0
def _onPygletMouseWheel(x, y, scroll_x, scroll_y):
    global mouseWheelRel
    mouseWheelRel = mouseWheelRel + numpy.array([scroll_x, scroll_y])
    msg = "Mouse: wheel shift=(%i,%i), pos=(%i,%i)"
    logging.data(msg % (scroll_x, scroll_y, x, y))
                i for i in range(joystick.numButtons) if
                joystick.newButtonState[i] and not joystick.oldButtonState[i]
            ]
            joystick.releasedButtons = [
                i for i in range(joystick.numButtons) if
                not joystick.newButtonState[i] and joystick.oldButtonState[i]
            ]
            joystick.newPressedButtons = [
                i for i in joystick.activeButtons
                if i in joystick.pressedButtons
            ]
            joystick.oldButtonState = joystick.newButtonState
            joystick.buttons = joystick.newPressedButtons
            [
                logging.data(
                    "joystick_{}_button: {}, pos=({:1.4f},{:1.4f})".format(
                        joystick.device_number, i, joystick.getX(),
                        joystick.getY())) for i in joystick.pressedButtons
            ]
            if len(joystick.buttons) > 0:  # state changed to a new click
                # abort routine on response
                continueRoutine = False

    # check for quit (typically the Esc key)
    if endExpNow or keyboard.Keyboard().getKeys(keyList=["escape"]):
        core.quit()

    # check if all components have finished
    if not continueRoutine:  # a component has requested a forced-end of Routine
        break
    continueRoutine = False  # will revert to True if at least one component still running
    for thisComponent in trialComponents:
 if t >= 0.0 and joystick.status == NOT_STARTED:
     # keep track of start time/frame for later
     joystick.tStart = t  # not accounting for scr refresh
     joystick.frameNStart = frameN  # exact frame index
     win.timeOnFlip(joystick, 'tStartRefresh')  # time at next scr refresh
     joystick.status = STARTED
     joystick.joystickClock.reset()
 if joystick.status == STARTED:  # only update if started and not finished!
     joystick.newButtonState = joystick.getAllButtons()[:]
     if joystick.newButtonState != joystick.oldButtonState: # New button press
         joystick.pressedButtons = [i for i in range(joystick.numButtons) if joystick.newButtonState[i] and not joystick.oldButtonState[i]]
         joystick.releasedButtons = [i for i in range(joystick.numButtons) if not joystick.newButtonState[i] and joystick.oldButtonState[i]]
         joystick.newPressedButtons = [i for i in joystick.activeButtons if i in joystick.pressedButtons]
         joystick.oldButtonState = joystick.newButtonState
         joystick.buttons = joystick.newPressedButtons
         [logging.data("joystick_{}_button: {}, pos=({:1.4f},{:1.4f})".format(joystick.device_number, i, joystick.getX(), joystick.getY())) for i in joystick.pressedButtons]
         if len(joystick.buttons) > 0:  # state changed to a new click
             # abort routine on response
             continueRoutine = False
 
 # check for quit (typically the Esc key)
 if endExpNow or keyboard.Keyboard().getKeys(keyList=["escape"]):
     core.quit()
 
 # check if all components have finished
 if not continueRoutine:  # a component has requested a forced-end of Routine
     break
 continueRoutine = False  # will revert to True if at least one component still running
 for thisComponent in trialComponents:
     if hasattr(thisComponent, "status") and thisComponent.status != FINISHED:
         continueRoutine = True
        today_date, operator, subject_code, subject_age, subject_gender,\
                SCANNER, Tr, Volumes, Skip, Sync = all_infos

    # Prepare out folder
    path_out = Dir_save + today_date + '_' + subject_code
    path_out = createOutFolder(path_out)

    # Set the log module to report warnings to the standard output window
    globalClock = core.Clock()
    logging.setDefaultClock(globalClock)
    logging.console.setLevel(logging.WARNING)
    lastLog = logging.LogFile(path_out + Log_name,
                              level=logging.DATA,
                              filemode='w',
                              encoding='utf8')
    logging.data("------------- " + strftime("%Y-%m-%d %H:%M:%S", gmtime()) +
                 " -------------")
    logging.data(pyschopy_prefs)
    logging.data("Saving in folder: " + path_out)
    logging.data("Operator: " + operator + "\n")
    logging.data("Subject. Code: " + subject_code + " - Age: " +
                 str(subject_age) + " - Gender: " + subject_gender)
    logging.data("Scanner. TR: " + Tr + " - Volumes: " + Volumes +
                 " - Skip: " + Skip + " - Sync: " + Sync + "\n")
    logging.data("Using %s (with %s driver) for sounds" %
                 (sound.audioLib, sound.audioDriver) + '\n')
    logging.data('***** Starting *****')

    # Start window
    win = visual.Window(Screen_dimensions,
                        monitor="mon",
                        units="norm",
Exemple #32
0
from __future__ import division

from psychopy import logging, core, visual

globalClock = core.Clock()  # if this isn't provided the log times will reflect secs since python started
logging.setDefaultClock(globalClock)

logging.console.setLevel(logging.DEBUG)  # receive nearly all messages
logDat = logging.LogFile('logLastRun.log',
    filemode='w',  # if you set this to 'a' it will append instead of overwriting
    level=logging.WARNING)  # errors, data and warnings will be sent to this logfile

# the following will go to any files with the appropriate minimum level set
logging.info('Something fairly unimportant')
logging.data('Something about our data. Data is likely very important!')
logging.warning('Handy while building your experiment - highlights possible flaws in code/design')
logging.error("You might have done something that PsychoPy can't handle! But hopefully this gives you some idea what.")

# some things should be logged timestamped on the next video frame
# For instance the time of a stimulus appearing is related to the flip:
win = visual.Window([400, 400])
for n in range(5):
    win.logOnFlip('frame %i occured' %n, level=logging.EXP)
    if n in [2, 4]:
        win.logOnFlip('an even frame occured', level=logging.EXP)
    win.flip()

# LogFiles can also simply receive direct input from the write() method
# messages using write() will be sent immediately, and are often not
# in correct chronological order with logged messages
     button_resp.frameNStart = frameN  # exact frame index
     win.timeOnFlip(button_resp, 'tStartRefresh')  # time at next scr refresh
     button_resp.status = STARTED
     # joyButtons checking is just starting
     win.callOnFlip(button_resp.clock.reset)  # t=0 on next screen flip
 if button_resp.status == STARTED:
     button_resp.newButtonState = button_resp.device.getAllButtons()[:]
     button_resp.pressedButtons = []
     button_resp.releasedButtons = []
     button_resp.newPressedButtons = []
     if button_resp.newButtonState != button_resp.oldButtonState:
         button_resp.pressedButtons = [i for i in range(button_resp.numButtons) if button_resp.newButtonState[i] and not button_resp.oldButtonState[i]]
         button_resp.releasedButtons = [i for i in range(button_resp.numButtons) if not button_resp.newButtonState[i] and button_resp.oldButtonState[i]]
         button_resp.oldButtonState = button_resp.newButtonState
         button_resp.newPressedButtons = [i for i in [0, 1, 2, 3, 4] if i in button_resp.pressedButtons]
         [logging.data("joystick_{}_button: {}".format(button_resp.device_number,i)) for i in button_resp.pressedButtons]
     theseKeys = button_resp.newPressedButtons
     if len(theseKeys) > 0:  # at least one key was pressed
         button_resp.keys = theseKeys[-1]  # just the last key pressed
         button_resp.rt = button_resp.clock.getTime()
         # a response ends the routine
         continueRoutine = False
 
 # check for quit (typically the Esc key)
 if endExpNow or keyboard.Keyboard().getKeys(keyList=["escape"]):
     core.quit()
 
 # check if all components have finished
 if not continueRoutine:  # a component has requested a forced-end of Routine
     break
 continueRoutine = False  # will revert to True if at least one component still running
Exemple #34
0
def waitKeys(maxWait=float('inf'), keyList=None, modifiers=False,
             timeStamped=False, clearEvents=True):
    """Same as `~psychopy.event.getKeys`, but halts everything
    (including drawing) while awaiting input from keyboard.

    :Parameters:
        maxWait : any numeric value.
            Maximum number of seconds period and which keys to wait for.
            Default is float('inf') which simply waits forever.
        keyList : **None** or []
            Allows the user to specify a set of keys to check for.
            Only keypresses from this set of keys will be removed from
            the keyboard buffer. If the keyList is `None`, all keys will be
            checked and the key buffer will be cleared completely.
            NB, pygame doesn't return timestamps (they are always 0)
        modifiers : **False** or True
            If True will return a list of tuples instead of a list of
            keynames. Each tuple has (keyname, modifiers). The modifiers
            are a dict of keyboard modifier flags keyed by the modifier
            name (eg. 'shift', 'ctrl').
        timeStamped : **False**, True, or `Clock`
            If True will return a list of tuples instead of a list of
            keynames. Each tuple has (keyname, time). If a `core.Clock`
            is given then the time will be relative to the `Clock`'s last
            reset.
        clearEvents : **True** or False
            Whether to clear the keyboard event buffer (and discard preceding
            keypresses) before starting to monitor for new keypresses.

    Returns None if times out.

    """
    if clearEvents:
        # Only consider keypresses from here onwards.
        # We need to invoke clearEvents(), but our keyword argument is
        # also called clearEvents. We can work around this conflict by
        # accessing the global scope explicitly.
        globals()['clearEvents']('keyboard')

    # Check for keypresses until maxWait is exceeded
    #
    # NB pygame.event does have a wait() function that will
    # do this and maybe leave more cpu idle time?

    timer = psychopy.core.Clock()
    got_keypress = False

    while not got_keypress and timer.getTime() < maxWait:
        # Pump events on pyglet windows if they exist.
        if havePyglet:
            defDisplay = pyglet.window.get_platform().get_default_display()
            for win in defDisplay.get_windows():
                win.dispatch_events()

        # Get keypresses and return if anything is pressed.
        keys = getKeys(keyList=keyList, modifiers=modifiers,
                       timeStamped=timeStamped)
        if keys:
            got_keypress = True

    if got_keypress:
        return keys
    else:
        logging.data('No keypress (maxWait exceeded)')
        return None
Exemple #35
0
    def waitForResponse(self):
        trial = self.trial
        node = self.node
        target = self.keytarget

        trialCompleted = False
        trialError = False
        interkeyWaitTime = None
        nPrevCorrect = 0

        while not trialCompleted:
            # Set the time to wait for a keypress
            # At most the trial time remaining, if we've pressed one key then
            # up to that amount
            maxWait = self.responseTimeLeft()
            if interkeyWaitTime:
                maxWait = min(interkeyWaitTime, maxWait)

            kbe = self.keyboard.waitForPresses(keys=keypress_map.keys(),
                                               maxWait=maxWait)
            keystate = self.keyboard.state.keys()
            exp_time = self.exp_timer.getTime()
            block_time = self.block_timer.getTime()
            timeLeft = self.responseTimeLeft()

            response = [int(x in keystate) for x in response_keys]
            nCorrect = sum([x and y for x, y in zip(response, target)])
            nIncorrect = sum(response) - nCorrect
            responseIsCorrect = (response == target)
            rt = self.trial_time - timeLeft

            if responseIsCorrect:
                # Correct
                trialCompleted = True
                trialError = False
            elif (nIncorrect == 0) and (nCorrect > nPrevCorrect):
                # Pressed a new correct key
                nPrevCorrect = nCorrect
                if interkeyWaitTime is None:
                    interkeyWaitTime = self.interkey_time
            elif timeLeft < 0 and not self.demo:  # timed out on the trial
                trialCompleted = True
                trialError = True
            elif interkeyWaitTime and not kbe and not self.demo:  # interkey timeout
                trialCompleted = True
                trialError = True
            elif (nIncorrect > 0):  # incorrect response
                # wrong key
                trialCompleted = True
                trialError = True

            event_data = {
                'nCorrect': nCorrect,
                'nIncorrect': nIncorrect,
                'timedOut': timeLeft < 0,
                'node': node,
                'target': target,
                'response': response,
                #   'SOA': self.jitter[self.trial],
                'trial': trial,
                'blockTime': block_time,
                'expTime': exp_time,
                'trialTime': rt,
                'error': trialError,
                'completed': trialCompleted
            }
            self.data.append(event_data)
            logging.data(event_data)
        self.accuracy_record.append(not trialError)
        return trialError