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
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
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
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})
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
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()
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)