Example #1
0
    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)
Example #2
0
    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)
Example #3
0
File: run.py Project: peircej/ioHub
    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()
Example #4
0
 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("--------------------------------------")
Example #5
0
    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))