def _handleEvents(self, events): # saves many events to pytables table at once. # EVENTS MUST ALL BE OF SAME TYPE!!!!! try: #ioHub.print2err("_handleEvent: ",self.active_experiment_id,self.active_session_id) if self.checkForExperimentAndSessionIDs(len(events)) is False: return False event=events[0] etype=event[DeviceEvent.EVENT_TYPE_ID_INDEX] #ioHub.print2err("etype: ",etype) eventClass=EventConstants.getClass(etype) etable=self.TABLES[eventClass.IOHUB_DATA_TABLE] #ioHub.print2err("eventClass: etable",eventClass,etable) np_events=[] for event in events: event[DeviceEvent.EVENT_EXPERIMENT_ID_INDEX]=self.active_experiment_id event[DeviceEvent.EVENT_SESSION_ID_INDEX]=self.active_session_id np_events.append(tuple(event)) np_array= N.array(np_events,dtype=eventClass.NUMPY_DTYPE) #ioHub.print2err('np_array:',np_array) etable.append(np_array) self.bufferedFlush(len(np_events)) except ioHub.ioHubError, e: ioHub.print2err(e)
def _handleEvent(self, event): try: if self.checkForExperimentAndSessionIDs(event) is False: return False etype=event[DeviceEvent.EVENT_TYPE_ID_INDEX] eventClass=EventConstants.getClass(etype) etable=self.TABLES[eventClass.IOHUB_DATA_TABLE] event[DeviceEvent.EVENT_EXPERIMENT_ID_INDEX]=self.active_experiment_id event[DeviceEvent.EVENT_SESSION_ID_INDEX]=self.active_session_id np_array= N.array([tuple(event),],dtype=eventClass.NUMPY_DTYPE) etable.append(np_array) self.bufferedFlush() except ioHub.ioHubError, e: ioHub.print2err(e)
def run(self,*args,**kwargs): """ """ # PLEASE REMEMBER , THE SCREEN ORIGIN IS ALWAYS IN THE CENTER OF THE SCREEN, # REGARDLESS OF THE COORDINATE SPACE YOU ARE RUNNING IN. THIS MEANS 0,0 IS SCREEN CENTER, # -x_min, -y_min is the screen bottom left # +x_max, +y_max is the screen top right # # *** RIGHT NOW, ONLY PIXEL COORD SPACE IS SUPPORTED. THIS WILL BE FIXED SOON. *** ENABLE_NOISY_MOUSE=True # Let's make some short-cuts to the devices we will be using in this 'experiment'. mouse=self.devices.mouse display=self.devices.display kb=self.devices.kb #Computer.enableHighPriority() # Create a psychopy window, using settings from Display device config psychoWindow = FullScreenWindow(display)#,res=(500,500),fullscr=False,allowGUI=True) # Hide the 'system mouse cursor' so we can display a cool gaussian mask for a mouse cursor. #mouse.setSystemCursorVisibility(False) # Set the mouse position to 0,0, which means the 'center' of the screen. mouse.setPosition((0.0,0.0)) # Read the current mouse position (should be 0,0) ;) currentPosition=mouse.getPosition() mouse.lockMouseToDisplayID(display.getIndex()) # Create an ordered dictionary of psychopy stimuli. An ordered dictionary is one that returns keys in the order # they are added, you you can use it to reference stim by a name or by 'zorder' psychoStim=OrderedDict() psychoStim['grating'] = visual.PatchStim(psychoWindow, mask="circle", size=75,pos=[-100,0], sf=.075) psychoStim['fixation'] =visual.PatchStim(psychoWindow, size=25, pos=[0,0], sf=0, color=[-1,-1,-1], colorSpace='rgb') psychoStim['keytext'] = visual.TextStim(psychoWindow, text=u'?', pos = [100,200], height=48, color=[-1,-1,-1], colorSpace='rgb',alignHoriz='center',alignVert='center',wrapWidth=400.0) psychoStim['ucodetext'] = visual.TextStim(psychoWindow, text=u'?', pos = [-100,200], height=48, color=[-1,-1,-1], colorSpace='rgb',alignHoriz='center',alignVert='center',wrapWidth=400.0) psychoStim['mods'] = visual.TextStim(psychoWindow, text=u'?', pos = [0,-200], height=48, color=[-1,-1,-1], colorSpace='rgb',alignHoriz='center',alignVert='center',wrapWidth=400.0) psychoStim['mouseDot'] =visual.GratingStim(psychoWindow,tex=None, mask="gauss", pos=currentPosition,size=(50,50),color='purple') # Clear all events from the global and device level event buffers. self.hub.clearEvents('all') QUIT_EXP=False # Loop until we get a keyboard event with the space, Enter (Return), or Escape key is pressed. while QUIT_EXP is False: # for each loop, update the grating phase psychoStim['grating'].setPhase(0.05, '+')#advance phase by 0.05 of a cycle # and update the mouse contingent gaussian based on the current mouse location mx,my=mouse.getPosition() if ENABLE_NOISY_MOUSE: mx=np.random.random_integers(mx-10,mx+10) my=np.random.random_integers(my-10,my+10) psychoStim['mouseDot'].setPos((mx,my)) # redraw the stim [psychoStim[stimName].draw() for stimName in psychoStim] # flip the psychopy window buffers, so the stim changes you just made get displayed. psychoWindow.flip() # it is on this side of the call that you know the changes have been displayed, so you can # make a call to the ioHub time method and get the time of the flip, as the built in # time methods represent both experiment process and ioHub server process time. # Most times in ioHub are represented sec.msec format to match that of Psychopy. flip_time=Computer.currentSec() # send a message to the iohub with the message text that a flip occurred and what the mouse position was. # since we know the ioHub server time the flip occurred on, we can set that directly in the event. self.hub.sendMessageEvent("Flip %s"%(str(currentPosition),), sec_time=flip_time) # get any new keyboard char events from the keyboard device # for each new keyboard character event, check if it matches one of the end example keys. for k in kb.getEvents(): if k.key.upper() in ['ESCAPE', ] and k.type==EventConstants.KEYBOARD_CHAR: print 'Quit key pressed: ',k.key,' for ',k.duration,' sec.' QUIT_EXP=True print u'{0}: time: {1}\t\tord: {2}.\t\tKey: [{3}]\t\tMods: {4}'.format(k.time,EventConstants.getName(k.type),k.ucode,k.key,k.modifiers) psychoStim['keytext'].setText(k.key) psychoStim['ucodetext'].setText(unichr(k.ucode)) psychoStim['mods'].setText(str(k.modifiers)) #for e in mouse.getEvents(): # print 'Event: ',e self.hub.clearEvents('all') # wait 250 msec before ending the experiment (makes it feel less abrupt after you press the key) actualDelay=self.hub.wait(0.250) print "Delay requested %.6f, actual delay %.6f, Diff: %.6f"%(0.250,actualDelay,actualDelay-0.250) # for fun, test getting a bunch of events at once, likely causing a mutlipacket getEvents() stime = Computer.currentSec() events=self.hub.getEvents() etime=Computer.currentSec() if events is None: events=[] print 'event count: ', len(events),' delay (msec): ',(etime-stime)*1000.0 # _close neccessary files / objects, 'disable high priority. psychoWindow.close()
def _processDeviceEventIteration(self): for device in self.devices: try: events=device._getNativeEventBuffer() #if events and len(events)>0: # ioHub.print2err("_processDeviceEventIteration.....", device._event_listeners) while len(events)>0: evt=events.popleft() e=device._getIOHubEventObject(evt) if e is not None: for l in device._getEventListeners(e[DeviceEvent.EVENT_TYPE_ID_INDEX]): l._handleEvent(e) except: ioHub.printExceptionDetailsToStdErr() ioHub.print2err("Error in processDeviceEvents: ", device, " : ", len(events), " : ", e) ioHub.print2err("Event type ID: ",e[DeviceEvent.EVENT_TYPE_ID_INDEX], " : " , EventConstants.getName(e[DeviceEvent.EVENT_TYPE_ID_INDEX])) ioHub.print2err("--------------------------------------")
def __init__(self, initial_time_offset, rootScriptPathDir, config=None): import ioHub Computer.isIoHubProcess=True Computer.globalClock=ioHub.ioClock(None,initial_time_offset) self._hookManager=None self.emrt_file=None self.config=config self.devices=[] self.deviceMonitors=[] self.sessionInfoDict=None self.experimentInfoList=None self.filterLookupByInput={} self.filterLookupByOutput={} self.filterLookupByName={} ioServer.eventBuffer=deque(maxlen=config.get('global_event_buffer',2048)) ioServer._logMessageBuffer=deque(maxlen=128) self._running=True # start UDP service self.udpService=udpServer(self,':%d'%config.get('udpPort',9000)) # read temp paths file ioHub.data_paths=None try: expJsonPath=os.path.join(rootScriptPathDir,'exp.paths') f=open(expJsonPath,'r') ioHub.data_paths=msgpack.loads(f.read()) f.flush() f.close() os.remove(expJsonPath) except: pass #ioHub.print2err("#### ioHub.data_paths: ",ioHub.data_paths) self._all_device_config_errors=dict() device_instance_list=[] try: #built device list and config from yaml config settings for iodevice in config.get('monitor_devices',()): for device_class_name,deviceConfig in iodevice.iteritems(): #ioHub.print2err("======================================================") #ioHub.print2err("Started load process for: {0}".format(device_class_name)) device_instance_and_config=self.addDeviceToMonitor(device_class_name,deviceConfig) if device_instance_and_config: device_instance_list.append(device_instance_and_config) else: ioHub.print2err('## Device was not started by the ioHub Server: ',device_class_name) raise ioHub.ioHubError("Device config validation failed") DeviceConstants.addClassMappings() EventConstants.addClassMappings() except: ioHub.print2err("Error during device creation ....") ioHub.printExceptionDetailsToStdErr() raise ioHub.ioHubError("Error during device creation ....") try: # dataStore setup if 'data_store' in config: experiment_datastore_config=config.get('data_store') default_datastore_config_path=os.path.join(ioHub.IO_HUB_DIRECTORY,'ioDataStore','default_iodatastore.yaml') _dslabel,default_datastore_config=load(file(default_datastore_config_path,'r'), Loader=Loader).popitem() for default_key,default_value in default_datastore_config.iteritems(): if default_key not in experiment_datastore_config: experiment_datastore_config[default_key]=default_value #ioHub.print2err("Merged ioDataStoreConfig: {0}".format(experiment_datastore_config)) if experiment_datastore_config.get('enable', True): #ioHub.print2err("Creating ioDataStore....") if ioHub.data_paths is None: resultsFilePath=rootScriptPathDir else: resultsFilePath=ioHub.data_paths[u'IOHUB_DATA'] self.createDataStoreFile(experiment_datastore_config.get('filename','events')+'.hdf5',resultsFilePath,'a',experiment_datastore_config) #ioHub.print2err("Created ioDataStore.") except: ioHub.print2err("Error during ioDataStore creation....") ioHub.printExceptionDetailsToStdErr() self.log("Adding ioServer and DataStore event listeners......") # add event listeners for saving events if self.emrt_file is not None: for device_instance,device_instance_config,eventIDs in device_instance_list: if device_instance_config['save_events']: device_instance._addEventListener(self.emrt_file,eventIDs) self.log("DataStore listener for device added: device: %s eventIDs: %s"%(device_instance.__class__.__name__,eventIDs)) #ioHub.print2err("DataStore listener for device added: device: %s eventIDs: %s"%(device_instance.__class__.__name__,eventIDs)) else: #ioHub.print2err("DataStore saving disabled for device: %s"%(device_instance.__class__.__name__,)) self.log("DataStore saving disabled for device: %s"%(device_instance.__class__.__name__,)) else: #ioHub.print2err("DataStore Not Evabled. No events will be saved.") self.log("DataStore Not Enabled. No events will be saved.") # try: # #built filter graph and config from yaml config settings # for iofilters in config.get('filters',()): # for filter_class,filterConfig in iofilters.iteritems(): # self.addFilterToMonitor(filter_class,filterConfig) # except: # ioHub.print2err("Error during filter creation ....") # ioHub.printExceptionDetailsToStdErr() deviceDict=ioServer.deviceDict iohub=self if ('Mouse' in deviceDict or 'Keyboard' in deviceDict): if Computer.system == 'win32': iohub.log("Creating pyHook Monitors....") #ioHub.print2err("Creating pyHook Monitors....") class pyHookDevice(object): def __init__(self): import pyHook self._hookManager=pyHook.HookManager() if 'Mouse' in deviceDict: #ioHub.print2err("Hooking Mouse.....") self._hookManager.MouseAll = deviceDict['Mouse']._nativeEventCallback self._hookManager.HookMouse() if 'Keyboard' in deviceDict: #ioHub.print2err("Hooking Keyboard.....") self._hookManager.KeyAll = deviceDict['Keyboard']._nativeEventCallback self._hookManager.HookKeyboard() iohub.log("WindowsHook PumpEvents Periodic Timer Created.") def _poll(self): import pythoncom # PumpWaitingMessages returns 1 if a WM_QUIT message was received, else 0 if pythoncom.PumpWaitingMessages() == 1: raise KeyboardInterrupt() #ioHub.print2err("Creating pyHook Monitor......") hookMonitor=DeviceMonitor(pyHookDevice(),0.00375) self.deviceMonitors.append(hookMonitor) #ioHub.print2err("Created pyHook Monitor.") elif Computer.system == 'linux2': # TODO: consider switching to xlib-ctypes implementation of xlib # https://github.com/garrybodsworth/pyxlib-ctypes iohub.log("Creating pyXHook Monitors....") import ioHub.devices.pyXHook self._hookManager = ioHub.devices.pyXHook.HookManager() if 'Keyboard' in deviceDict: ioHub.print2err("Hooking Keyboard.....") self._hookManager.HookKeyboard() self._hookManager.KeyDown = deviceDict['Keyboard']._nativeEventCallback self._hookManager.KeyUp = deviceDict['Keyboard']._nativeEventCallback if 'Mouse' in deviceDict: ioHub.print2err("Hooking Mouse.....") self._hookManager.HookMouse() self._hookManager.MouseAllButtonsDown = deviceDict['Mouse']._nativeEventCallback self._hookManager.MouseAllButtonsUp = deviceDict['Mouse']._nativeEventCallback self._hookManager.MouseAllMotion = deviceDict['Mouse']._nativeEventCallback #ioHub.print2err("Starting pyXHook.HookManager.....") self._hookManager.start() iohub.log("pyXHook Thread Created.") #ioHub.print2err("pyXHook.HookManager thread created.") else: # OSX if 'Mouse' in deviceDict: mouseHookMonitor=DeviceMonitor(deviceDict['Mouse'],0.004) self.deviceMonitors.append(mouseHookMonitor) deviceDict['Mouse']._CGEventTapEnable(deviceDict['Mouse']._tap, True) if 'Keyboard' in deviceDict: kbHookMonitor=DeviceMonitor(deviceDict['Keyboard'],0.004) self.deviceMonitors.append(kbHookMonitor) deviceDict['Keyboard']._CGEventTapEnable(deviceDict['Keyboard']._tap, True) # import ioHub.devices.pyXHook # # self._hookManager = ioHub.devices.pyXHook.HookManager() # if 'Keyboard' in deviceDict: # ioHub.print2err("Hooking Keyboard.....") # self._hookManager.HookKeyboard() # self._hookManager.KeyDown = deviceDict['Keyboard']._nativeEventCallback # self._hookManager.KeyUp = deviceDict['Keyboard']._nativeEventCallback # if 'Mouse' in deviceDict: # ioHub.print2err("Hooking Mouse.....") # self._hookManager.HookMouse() # self._hookManager.MouseAllButtonsDown = deviceDict['Mouse']._nativeEventCallback # self._hookManager.MouseAllButtonsUp = deviceDict['Mouse']._nativeEventCallback # self._hookManager.MouseAllMotion = deviceDict['Mouse']._nativeEventCallback # # #ioHub.print2err("Starting pyXHook.HookManager.....") # self._hookManager.start() # iohub.log("pyXHook Thread Created.") #ioHub.print2err("pyXHook.HookManager thread created.") self.log("Time Offset: {0}".format(initial_time_offset))