Esempio n. 1
0
 def __init__(self, device, event_type, event_attribute_conditions={}, repeat_count=-1,
              trigger_function=lambda a, b, c: True, user_kwargs={}):
     Trigger.io = ioHubConnection.getActiveConnection()
     Trigger.__init__(self, trigger_function, user_kwargs, repeat_count)
     self.device = device
     self.event_type = event_type
     self.event_attribute_conditions = event_attribute_conditions
Esempio n. 2
0
    def __init__(self,
                 start_time,
                 delay,
                 repeat_count=0,
                 trigger_function=lambda a, b, c: True,
                 user_kwargs={}):
        Trigger.io = ioHubConnection.getActiveConnection()
        Trigger.__init__(self, trigger_function, user_kwargs, repeat_count)

        self._start_time = start_time

        if start_time is None or not callable(start_time):

            def startTimeFunc():
                if self._start_time is None:
                    self._start_time = getTime()
                return self._start_time

            self.startTime = startTimeFunc
        else:
            self.startTime = start_time

        self.delay = delay
        if not callable(delay):

            def delayFunc():
                return delay

            self.delay = delayFunc
Esempio n. 3
0
def stopHubProcess():
    from psychopy.iohub.client import ioHubConnection

    io = ioHubConnection.getActiveConnection()
    assert io != None

    io_proc = Computer.getIoHubProcess()
    io_proc_pid = io_proc.pid
    assert io_proc != None and psutil.pid_exists(io_proc_pid)

    # Stop iohub server, ending process.
    io.quit()

    # Enure iohub proc has terminated.
    assert not psutil.pid_exists(io_proc_pid)

    assert ioHubConnection.getActiveConnection() is None
Esempio n. 4
0
def stopHubProcess():
    from psychopy.iohub.client import ioHubConnection

    io = ioHubConnection.getActiveConnection()
    assert io != None

    io_proc = Computer.getIoHubProcess()
    io_proc_pid = io_proc.pid
    assert io_proc != None and psutil.pid_exists(io_proc_pid)

    # Stop iohub server, ending process.
    io.quit()

    # Enure iohub proc has terminated.
    assert not psutil.pid_exists(io_proc_pid)

    assert ioHubConnection.getActiveConnection() is None
Esempio n. 5
0
 def __init__(self, key, on_press=False):
     Trigger.io = ioHubConnection.getActiveConnection()
     if on_press:
         etype = EventConstants.KEYBOARD_PRESS
     else:
         etype = EventConstants.KEYBOARD_RELEASE
     DeviceEventTrigger.__init__(self, self.io.devices.keyboard, event_type=etype,
                                 event_attribute_conditions={'key': key})
Esempio n. 6
0
 def __init__(self, trigger_function=lambda a, b, c: True, user_kwargs={}, repeat_count=0):
     Trigger.io = ioHubConnection.getActiveConnection()
     self.trigger_function = trigger_function
     self.user_kwargs = user_kwargs
     self._last_triggered_event = None
     self._last_triggered_time = None
     self.repeat_count = repeat_count
     self.triggered_count = 0
Esempio n. 7
0
    def __init__(
        self,
        bounds=None,
        shape=None,  # Defines the number of columns and rows of
        # positions needed. If shape is an array of
        # two elements, it defines the col,row shape
        # for position layout. Position count will
        # equal rows*cols. If shape is a single
        # int, the position grid col,row shape will
        # be shape x shape.
        posCount=None,  # Defines the number of positions to create
        # without any col,row position constraint.
        leftMargin=None,  # Specify the minimum valid horz position.
        rightMargin=None,  # Limit horz positions to be < max horz
        # position minus rightMargin.
        topMargin=None,  # Limit vert positions to be < max vert
        # position minus topMargin.
        bottomMargin=None,  # Specify the minimum valid vert position.
        scale=1.0,  # Scale can be one or two numbers, each
        # between 0.0 and 1.0. If a tuple is
        # provided, it represents the horz, vert
        # scale to be applied to window width,
        # height. If a single number is
        # given, the same scale will be applied to
        # both window width and height. The scaled
        # window size is centered on the original
        # window size to define valid position area.
        posList=None,  # Provide an existing list of (x,y)
        # positions. If posList is provided, the
        # shape, posCount, margin and scale arg's
        # are ignored.
        noiseStd=None,  # Add a random shift to each position based
        # on a normal distribution with mean = 0.0
        # and sigma equal to noiseStd. Specify
        # value based on units being used.
        firstposindex=0,  # Specify which position in the position
        # list should be displayed first. This
        # position is not effected by randomization.
        repeatFirstPos=False  # If the first position in the list should
        # be provided as the last position as well,
        # set to True. In this case, the number of
        # positions returned will be position
        # count + 1. False indicated the first
        # position should not be repeated.
    ):
        """
        PositionGrid provides a flexible way to generate a set of x,y position
        values within the boundaries of the psychopy window object provided.

        The class provides a set of arguments that represent commonly needed
        constraints when creating a target position list, supporting a
        variety of position arrangements.

        PositionGrid supports the len() function, and returns the number of
        positions generated based on the supplied parameters. If repeatFirstPos
        is true, len(posgrid) == number of unique positions + 1 (a repeat of the
        first position value).

        PositionGrid is a generator, so the normal way to access the positions from
        the class is to use a for loop or with statement:

        posgrid = PositionGrid(....)
        for pos in posgrid:
            # do something cool with the pos
            print(pos)

        :param bounds:
        :param shape:
        :param posCount:
        :param leftMargin:
        :param rightMargin:
        :param topMargin:
        :param bottomMargin:
        :param scale:
        :param posList:
        :param noiseStd:
        :param firstposindex:
        :param repeatFirstPos:
        """
        self.posIndex = 0
        self.positions = None
        self.posOffsets = None

        self.bounds = bounds
        if self.bounds is None:
            self.bounds = ioHubConnection.getActiveConnection(
            ).devices.display.getCoordBounds()

        winSize = self.bounds[2] - self.bounds[0], self.bounds[
            3] - self.bounds[1]
        self.firstposindex = firstposindex

        self.repeatfirstpos = repeatFirstPos

        self.horzStd, self.vertStd = None, None
        if noiseStd:
            if hasattr(noiseStd, '__len__'):
                self.horzStd, self.vertStd = noiseStd
            else:
                self.horzStd, self.vertStd = noiseStd, noiseStd

        horzScale, vertScale = None, None
        if scale:
            if hasattr(scale, '__len__'):
                horzScale, vertScale = scale
            else:
                horzScale, vertScale = scale, scale

        rowCount, colCount = None, None
        if shape:
            if hasattr(shape, '__len__'):
                colCount, rowCount = shape
            else:
                rowCount, colCount = shape, shape

        if posList:
            # User has provided the target positions, use posList to set
            # self.positions as array of x,y pairs.
            if len(posList) == 2 and len(posList[0]) != 2 and len(
                    posList[0]) == len(posList[1]):
                # positions were provided in ((x1,x2,..,xn),(y1,y2,..,yn))
                # format
                self.positions = np.column_stack((posList[0], posList[1]))
            elif len(posList[0]) == 2:
                self.positions = np.asarray(posList)
            else:
                raise ValueError(
                    'PositionGrid posList kwarg must be in ((x1,y1),(x2,y2),..,(xn,yn))'
                    ' or ((x1,x2,..,xn),(y1,y2,..,yn)) format')

        if self.positions is None and (posCount or (rowCount and colCount)):
            # Auto generate position list based on criteria
            # provided.
            if winSize is not None:
                pixw, pixh = winSize
                xmin = 0.0
                xmax = 1.0
                ymin = 0.0
                ymax = 1.0

                if leftMargin:
                    if leftMargin < pixw:
                        xmin = leftMargin / pixw
                    else:
                        raise ValueError(
                            'PositionGrid leftMargin kwarg must be < winSize[0]'
                        )
                if rightMargin:
                    if rightMargin < pixw:
                        xmax = 1.0 - rightMargin / pixw
                    else:
                        raise ValueError(
                            'PositionGrid rightMargin kwarg must be < winSize[0]'
                        )
                if topMargin:
                    if topMargin < pixh:
                        ymax = 1.0 - topMargin / pixh
                    else:
                        raise ValueError(
                            'PositionGrid topMargin kwarg must be < winSize[1]'
                        )
                if bottomMargin:
                    if bottomMargin < pixh:
                        ymin = bottomMargin / pixh
                    else:
                        raise ValueError(
                            'PositionGrid bottomMargin kwarg must be < winSize[1]'
                        )

                if horzScale:
                    if 0.0 < horzScale <= 1.0:
                        xmin += (1.0 - horzScale) / 2.0
                        xmax -= (1.0 - horzScale) / 2.0
                else:
                    raise ValueError(
                        'PositionGrid horzScale kwarg must be 0.0 > horzScale <= 1.0'
                    )

                if vertScale:
                    if 0.0 < vertScale <= 1.0:
                        ymin += (1.0 - vertScale) / 2.0
                        ymax -= (1.0 - vertScale) / 2.0
                else:
                    raise ValueError(
                        'PositionGrid vertScale kwarg must be 0.0 > vertScale <= 1.0'
                    )
                if posCount:
                    colCount = int(np.sqrt(posCount))
                    rowCount = colCount
                    xps = np.random.uniform(xmin, xmax,
                                            colCount) * pixw - pixw / 2.0
                    yps = np.random.uniform(ymin, ymax,
                                            rowCount) * pixh - pixh / 2.0
                else:
                    xps = np.linspace(xmin, xmax, colCount) * pixw - pixw / 2.0
                    yps = np.linspace(ymin, ymax, rowCount) * pixh - pixh / 2.0

                xps, yps = np.meshgrid(xps, yps)
                self.positions = np.column_stack(
                    (xps.flatten(), yps.flatten()))

            else:
                raise ValueError(
                    'PositionGrid posCount kwarg also requires winSize to be provided.'
                )

        if self.positions is None:
            raise AttributeError(
                'PositionGrid is unable to generate positions based on the provided kwargs.'
            )

        if self.firstposindex and self.firstposindex > 0:
            fpos = self.positions[self.firstposindex]
            self.positions = np.delete(self.positions, self.firstposindex, 0)
            self.positions = np.insert(self.positions, 0, fpos, 0)

        self._generatePosOffsets()
Esempio n. 8
0
    def __init__(self, device=-1, bufferSize=10000, waitForStart=False, clock=None, backend=None):
        """Create the device (default keyboard or select one)

        Parameters
        ----------
        device: int or dict

            On Linux/Mac this can be a device index
            or a dict containing the device info (as from :func:`getKeyboards`)
            or -1 for all devices acting as a unified Keyboard

        bufferSize: int

            How many keys to store in the buffer (before dropping older ones)

        waitForStart: bool (default False)

            Normally we'll start polling the Keyboard at all times but you
            could choose not to do that and start/stop manually instead by
            setting this to True

        """
        global havePTB

        if self._backend is None and backend in ['iohub', 'ptb', 'event', '']:
            Keyboard._backend = backend

        if self._backend is None:
            Keyboard._backend = ''

        if backend and self._backend != backend:
            logging.warning("keyboard.Keyboard already using '%s' backend. Can not switch to '%s'" % (self._backend,
                                                                                                      backend))

        self.status = NOT_STARTED
        # Initiate containers for storing responses
        self.keys = []  # the key(s) pressed
        self.corr = 0  # was the resp correct this trial? (0=no, 1=yes)
        self.rt = []  # response time(s)
        self.time = []  # Epoch

        if clock:
            self.clock = clock
        else:
            self.clock = psychopy.clock.Clock()

        if Keyboard._backend in ['', 'iohub']:
            from psychopy.iohub.client import ioHubConnection
            from psychopy.iohub.devices import Computer
            if not ioHubConnection.getActiveConnection() and Keyboard._backend == 'iohub':
                # iohub backend was explicitly requested, but iohub is not running, so start it up
                # setting keyboard to use standard psychopy key mappings
                from psychopy.iohub import launchHubServer
                launchHubServer(Keyboard=dict(use_keymap='psychopy'))

            if ioHubConnection.getActiveConnection() and Keyboard._iohubKeyboard is None:
                Keyboard._iohubKeyboard = ioHubConnection.getActiveConnection().getDevice('keyboard')
                Keyboard._iohubOffset = Computer.global_clock.getLastResetTime()
                Keyboard._backend = 'iohub'

        if Keyboard._backend in ['', 'ptb'] and havePTB:
            Keyboard._backend = 'ptb'
            Keyboard._ptbOffset = self.clock.getLastResetTime()
            # get the necessary keyboard buffer(s)
            if sys.platform == 'win32':
                self._ids = [-1]  # no indexing possible so get the combo keyboard
            else:
                allInds, allNames, allKBs = hid.get_keyboard_indices()
                if device == -1:
                    self._ids = allInds
                elif type(device) in [list, tuple]:
                    self._ids = device
                else:
                    self._ids = [device]

            self._buffers = {}
            self._devs = {}
            for devId in self._ids:
                # now we have a list of device IDs to monitor
                if devId == -1 or devId in allInds:
                    buffer = _keyBuffers.getBuffer(devId, bufferSize)
                    self._buffers[devId] = buffer
                    self._devs[devId] = buffer.dev

            # Is this right, waiting if waitForStart=False??
            if not waitForStart:
                self.start()

        if Keyboard._backend in ['', 'event']:
            global event
            from psychopy import event
            Keyboard._backend = 'event'

        logging.info('keyboard.Keyboard is using %s backend.' % Keyboard._backend)