def shutdown(self): try: self._running=False if Computer.system=='linux2': if self._hookManager: self._hookManager.cancel() while len(self.deviceMonitors) > 0: m=self.deviceMonitors.pop(0) m.running=False self.clearEventBuffer() try: self.closeDataStoreFile() except: pass while len(self.devices) > 0: d=self.devices.pop(0) try: if d is not None: d._close() except: pass gevent.sleep() except: ioHub.print2err("Error in ioSever.shutdown():") ioHub.printExceptionDetailsToStdErr()
def getPositionAndDelta(self,return_display_index=False): """ Returns a tuple of tuples, being the current position of the ioHub Mouse Device as an (x,y) tuple, and the amount the mouse position changed the last time it was updated (dx,dy). Mouse Position and Delta are in display coordinate units. Args: None Return (tuple): ( (x,y), (dx,dy) ) position of mouse, change in mouse position, both in Display coordinate space. """ try: cpos=self._position lpos=self._lastPosition change_x=cpos[0]-lpos[0] change_y=cpos[1]-lpos[1] if return_display_index is True: return (cpos, (change_x,change_y), self._display_index) return cpos, (change_x,change_y) except Exception, e: ioHub.print2err(">>ERROR getPositionAndDelta: "+str(e)) ioHub.printExceptionDetailsToStdErr() if return_display_index is True: return ((0.0,0.0),(0.0,0.0), self._display_index) return (0.0,0.0),(0.0,0.0)
def _nativeEventCallback(self,labjack_data): if not self.isReportingEvents(): return False logged_time=Computer.getTime() start_pre,start_post,analog_data=labjack_data str_proto='AIN%d' channel_index_list=range(self.input_channel_count) ain=[] ain_counts=[] for c in channel_index_list: ai=analog_data[str_proto%c] ain.append(ai) ain_counts.append(len(ai)) #ioHub.print2err("Channel Counts: {0} {1}".format(logged_time,ain_counts)) ain_counts=tuple(ain_counts) if ain_counts[0] != ain_counts[-1]: err_str="Channel Sample Count Mismatch: " for c in channel_index_list: err_str+='{%d}, '%c err_str=err_str[:-2] ioHub.print2err(err_str.format(*ain_counts)) device_time=0.0 iohub_time=0.0 delay=0.0 confidence_interval=start_post-start_pre event =[ 0, # exp id 0, # session id 0, #device id (not currently used) 0, # event id MultiChannelAnalogInputEvent.EVENT_TYPE_ID, # event type device_time, # device time logged_time, # logged time iohub_time, # hub time confidence_interval, # confidence interval delay, # delay 0 # filter_id ] for s in range(ain_counts[0]): multi_channel_event=list(event) multi_channel_event[3]=Computer._getNextEventID() multi_channel_event[5]=float(self._scan_count)/float(self.channel_sampling_rate) multi_channel_event[7]=multi_channel_event[4]+start_post multi_channel_event[9]=logged_time-multi_channel_event[6] multi_channel_event.extend([ain[a][s] for a in channel_index_list]) self._addNativeEventToBuffer(multi_channel_event) self._scan_count+=1 self._last_callback_time=logged_time return True
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 __init__(self, *args, **kwargs): """ """ AnalogInputDevice.__init__(self, *args, **kwargs) self._labjack=None if self.model_name in self._SUPPORTED_MODELS.keys(): try: self._labjack = self._SUPPORTED_MODELS[self.model_name]() self._calibration_data=self._labjack.getCalibrationData() self._labjack.streamConfig( NumChannels = self.input_channel_count, ChannelNumbers = range(self.input_channel_count), ChannelOptions = [ 0 ]*self.input_channel_count, SettlingFactor = self.settling_factor, ResolutionIndex = self.resolution_index, SampleFrequency = self.channel_sampling_rate) self._data_streaming_thread=LabJackDataReader(self) self._data_streaming_thread.start() except: ioHub.print2err("ERROR DURING LABJACK INIT") ioHub.printExceptionDetailsToStdErr() else: ioHub.print2err("AnalogInput Model %s is not supported. Supported models are %s, using model_name parameter."%(self.model_name,str(self._SUPPORTED_MODELS.keys()),)) raise ioDeviceError(self,"AnalogInput Model not supported: %s"%(self.model_name)) sys.exit(0) self._scan_count=0
def _handleNativeEvent(self,*args,**kwargs): """ This method is called every time there is new eye data available from the Tobii system, which will be roughly equal to the sampling rate eye data is being recorded at. The callback needs to return as quickly as possible so there is no chance of overlapping calls being made to the callback. Therefore this method simply puts the event data received from the eye tracker device, and the local ioHub time the callback was called, into a buffer for processing by the ioHub event system. """ if self.isReportingEvents(): try: eye_data_event=args[1] logged_time_iohub_usec=Computer.getTime()/self.DEVICE_TIMEBASE_TO_SEC logged_time_tobii_local_usec=self._tobii._getTobiiClockTime() data_time_in_tobii_local_time=self._tobii._sync_manager.convert_from_remote_to_local(eye_data_event.Timestamp) data_delay=logged_time_tobii_local_usec-data_time_in_tobii_local_time logged_time=logged_time_iohub_usec*self.DEVICE_TIMEBASE_TO_SEC device_event_time=data_time_in_tobii_local_time*self.DEVICE_TIMEBASE_TO_SEC iohub_event_time=(logged_time_iohub_usec-data_delay)*self.DEVICE_TIMEBASE_TO_SEC # in sec.msec_usec data_delay=data_delay*self.DEVICE_TIMEBASE_TO_SEC self._addNativeEventToBuffer((logged_time,device_event_time,iohub_event_time,data_delay,eye_data_event)) return True except: ioHub.print2err("ERROR IN _handleNativeEvent") ioHub.printExceptionDetailsToStdErr() else: ioHub.print2err("self._handleNativeEvent called but isReportingEvents == false")
def run(self): # Check if the extension is present if not self.record_dpy.has_extension("RECORD"): ioHub.print2err("RECORD extension not found. ioHub can not use python Xlib. Exiting....") return False # Create a recording context; we only want key and mouse events self.ctx = self.record_dpy.record_create_context( 0, [record.AllClients], [{ 'core_requests': (0, 0), 'core_replies': (0, 0), 'ext_requests': (0, 0, 0, 0), 'ext_replies': (0, 0, 0, 0), 'delivered_events': (0, 0), 'device_events': tuple(self.contextEventMask), #(X.KeyPress, X.ButtonPress), 'errors': (0, 0), 'client_started': False, 'client_died': False, }]) # Enable the context; this only returns after a call to record_disable_context, # while calling the callback function in the meantime self.record_dpy.record_enable_context(self.ctx, self.processevents) # Finally free the context self.record_dpy.record_free_context(self.ctx)
def sendCommand(self, key, value=None): """ """ try: if self._eyegaze_control: if key == 'get_control_status': rdict=dict() for a in self._eyegaze_control.__slots__: v=getattr(self._eyegaze_control,a) rdict[a]=v return rdict elif key == 'get_config': egConfig=pEyeGaze._stEgConfig(0,0) r = pEyeGaze.EgGetConfig(byref(self._eyegaze_control),byref(egConfig),sizeof(egConfig)) rdict=None if r==0: rdict= {'iNVis':egConfig.iNVis, 'bEyefollower': egConfig.bEyefollower} egConfig=None return rdict else: ioHub.print2err('WARNING: EyeGaze command not handled: {0} = {1}.'.format()) except Exception, e: return createErrorResult("IOHUB_DEVICE_EXCEPTION", error_message="An unhandled exception occurred on the ioHub Server Process.", method="EyeTracker.sendCommand", key=key,value=value, error=e)
def __init__(self,*args,**kwargs): """ EyeTracker class. This class is to be extended by each eye tracker specific implemetation of the pyEyeTrackerInterface. Please review the documentation page for the specific eye tracker model that you are using the pyEyeTrackerInterface with to get the appropriate module path for that eye tracker; for example, if you are using an interface that supports eye trackers developed by EyeTrackingCompanyET, you may initialize the eye tracker object for that manufacturer something similar too : eyeTracker = hub.eyetrackers.EyeTrackingCompanyET.EyeTracker(**kwargs) where hub is the instance of the ioHubClient class that has been created for your experiment. **kwargs are an optional set of named parameters. **If an instance of EyeTracker has already been created, trying to create a second will raise an exception. Either destroy the first instance and then create the new instance, or use the class method EyeTracker.getInstance() to access the existing instance of the eye tracker object.** """ if EyeTracker._INSTANCE is not None: raise ioHub.devices.ioDeviceError(self.__class__.__name__,"EyeTracker object has already been created; only one instance can exist. Delete existing instance before recreating EyeTracker object.") # >>>> eye tracker config EyeTracker.eyeTrackerConfig=kwargs['dconfig'] #print " #### EyeTracker Configuration #### " #print self.eyeTrackerConfig #print '' # <<<< ## Load quicklink dll EyeTracker._DLL = windll.LoadLibrary("C:\\Program Files\\EyeTechDS\\QuickLink2_2.5.1.0\\bin\\QuickLink2.dll") ioHub.print2err("DLL: ",EyeTracker._DLL) # create Device level class setting dictionary and pass it Device constructor deviceSettings= dict(instance_code=self.eyeTrackerConfig['instance_code'], category_id=ioHub.devices.EventConstants.DEVICE_CATERGORIES['EYE_TRACKER'], type_id=ioHub.devices.EventConstants.DEVICE_TYPES['EYE_TRACKER_DEVICE'], device_class=self.eyeTrackerConfig['device_class'], user_label=self.eyeTrackerConfig['name'], os_device_code='OS_DEV_CODE_NOT_SET', max_event_buffer_length=self.eyeTrackerConfig['event_buffer_length']) Device.__init__(self,**deviceSettings) # set this instance as 'THE' instance of the eye tracker. EyeTracker._INSTANCE=self EyeTracker.DEVICE_START_TIME=0.0 # >>>> eye tracker setting to config (if possible) runtimeSettings=self.eyeTrackerConfig['runtime_settings'] # >>>> Display / Calibration related information to use for config if possible EyeTracker.displaySettings = self.eyeTrackerConfig['display_settings'] ioHub.print2err("Start createFrameTest") testFrame=createFrameTest() ioHub.print2err(testFrame.PixelData[0:testFrame.Width*testFrame.Height]) ioHub.print2err("End createFrameTest") ioHub.print2err("Done EyeTech Init")
def shutDown(self): try: self.disableHighPriority() self.iohub.shutdown() self._running=False self.stop() except: ioHub.print2err("Error in ioSever.shutdown():") ioHub.printExceptionDetailsToStdErr() sys.exit(1)
def on_compute_calibration(self,*args,**kwargs): self._lastCalibrationReturnCode=args[0] if self._lastCalibrationReturnCode!=0: ioHub.print2err("ERROR: Tobii Calibration Calculation Failed. Error code: {0}".format(self._lastCalibrationReturnCode)) self._lastCalibrationOK=False self._msg_queue.put("CALIBRATION_COMPUTATION_FAILED") else: self._msg_queue.put("CALIBRATION_COMPUTATION_COMPLETE") self._lastCalibrationOK=True
def setAllOtherProcessesAffinity(self, processorList, excludeProcessByIDList=[]): """ """ for p in psutil.process_iter(): if p.pid not in excludeProcessByIDList: try: p.set_cpu_affinity(processorList) print2err('Set OK process affinity: '+str(p.name)+" : "+str(p.pid)) except Exception: print2err('Error setting process affinity: '+str(p.name)+" : "+str(p.pid))
def sendMessage(self,message_contents,time_offset=None): """ """ try: if self._eyegaze_control: ioHub.print2err("EyeGaze sendMessage not yet implemented") return EyeTrackerConstants.FUNCTIONALITY_NOT_SUPPORTED except Exception, e: return createErrorResult("IOHUB_DEVICE_EXCEPTION", error_message="An unhandled exception occurred on the ioHub Server Process.", method="EyeTracker.sendMessage", message_contents=message_contents,time_offset=time_offset, error=e)
def _determineDisplayCoordSpace(self): dispCoordType=self._settings['reporting_unit_type'] for ctype,cvalues in self.ccordinateTypes.iteritems(): if dispCoordType in cvalues: Display._displayCoordinateType=ctype break if Display._displayCoordinateType is None: Display._displayCoordinateType='pix' ioHub.print2err("ERROR: Display._determineDIsplayCoordSpace: Unknown coord space parameter setting; using 'pix': "+dispCoordType) return Display._displayCoordinateType
def getPositionAndChange(self): try: cpos = self._position lpos = self._lastPosition change_x = cpos[0] - lpos[0] change_y = cpos[1] - lpos[1] if change_x or change_y: return cpos, (change_x, change_y) return cpos, None except Exception, e: ioHub.print2err(">>ERROR getPositionAndChange: " + str(e)) ioHub.printExceptionDetailsToStdErr() return (0.0, 0.0), (0.0, 0.0)
def getPositionAndChange(self): try: cpos=self._position lpos=self._lastPosition change_x=cpos[0]-lpos[0] change_y=cpos[1]-lpos[1] if change_x or change_y: return cpos, (change_x,change_y) return cpos, None except Exception, e: ioHub.print2err(">>ERROR getPositionAndChange: "+str(e)) ioHub.printExceptionDetailsToStdErr() return (0.0,0.0),(0.0,0.0)
def _close(self): #/* The BACKGROUND operation must be explicitly stopped #Parameters: #BoardNum :the number used by CB.CFG to describe this board #FunctionType: A/D operation (AIFUNCTION)*/ # this should be taking board ID and AIFUNCTION # but when ever I give it second param ctypes throws # a `4 bytes too much`error ulStat = self._DLL.cbStopBackground (c_int32(self.device_number)) ioHub.print2err("cbStopBackground: ",ulStat) ulStat=self._DLL.cbWinBufFree(cast(self._memory_handle,POINTER(c_void_p))) ioHub.print2err("cbWinBufFree _memory_handle: ",ulStat)
def run(self): getTime=Computer.getTime try: self.running = True while self.running: # wait for threading event to become True self.stream_start_time_pre=None self.stream_start_time_post=None self.stream_stop_time=None self.request_count = 0 self.channel_array_read_count = 0 self.missed_count = 0 self.error_count = 0 self.stream_data_event.wait(None) # start streaming self.stream_start_time_pre = getTime() self.labjack_device.streamStart() self.stream_start_time_post = getTime() # Stream until either the ioHub server has set running to False, # or until threading event is False again while self.running and self.isStreamingData(): # Calling with convert = False, # because we are going to convert in the main thread. returnDict = self.labjack_device.streamData(convert = False).next() # record and print any errors during streaming if returnDict['errors'] != 0: self.error_count+=returnDict['errors'] ioHub.print2err('ERRORS DURING LABJACK STREAMING: current: {0} total: {1}'.format(returnDict['errors'],self.error_count)) if returnDict['missed'] != 0: self.missed_count+=returnDict['missed'] ioHub.print2err('DROPPED SAMPLES DURING LABJACK STREAMING: current: {0} total: {1}'.format(returnDict['missing'],self.missed_count)) # put a copy of the new analog input events in the queue for pickup by the ioHub Device Poll self.iohub_device._nativeEventCallback([self.stream_start_time_pre, self.stream_start_time_post, copy.deepcopy(self.labjack_device.processStreamData(returnDict['result']))]) self.request_count += 1 self.labjack_device.streamStop() self.stream_stop_time=getTime() total = self.request_count * self.labjack_device.packetsPerRequest * self.labjack_device.streamSamplesPerPacket total -= self.missed_count run_time = self.stream_stop_time-self.stream_start_time_post ioHub.print2err("%s samples / %s seconds = %s Hz" % ( total, run_time, float(total)/run_time )) self.iohub_device=None self.labjack_device=None except: ioHub.print2err("ERROR IN THREAD RUN:") ioHub.printExceptionDetailsToStdErr()
def _determineDisplayCoordSpace(self): dispCoordType = self._settings['reporting_unit_type'] for ctype, cvalues in self.ccordinateTypes.iteritems(): if dispCoordType in cvalues: Display._displayCoordinateType = ctype break if Display._displayCoordinateType is None: Display._displayCoordinateType = 'pix' ioHub.print2err( "ERROR: Display._determineDIsplayCoordSpace: Unknown coord space parameter setting; using 'pix': " + dispCoordType) return Display._displayCoordinateType
def _nativeSetSystemCursorVisibility(self,v): if Mouse._xfixsdll is None: ioHub.print2err("Xfixes DLL could not be loaded. Cursor visiblity support is unavailable.") return True if v is True and self._nativeGetSystemCursorVisibility() is False: Mouse._xfixsdll.XFixesShowCursor(Mouse._xdisplay,self._display_device._xwindow) Mouse._xfixsdll.XFlush(Mouse._xdisplay) self._cursorVisible=True elif v is False and self._nativeGetSystemCursorVisibility() is True: Mouse._xfixsdll.XFixesHideCursor(Mouse._xdisplay,self._display_device._xwindow) Mouse._xfixsdll.XFlush(Mouse._xdisplay) self._cursorVisible=False return self._nativeGetSystemCursorVisibility()
def _registerEventMonitors(self): if self._eyetrackerinterface._iohub_server: for dev in self._eyetrackerinterface._iohub_server.devices: #ioHub.print2err("dev: ",dev.__class__.__name__) if dev.__class__.__name__ == 'Keyboard': kbDevice=dev if kbDevice: eventIDs=[] for event_class_name in kbDevice.__class__.EVENT_CLASS_NAMES: eventIDs.append(getattr(EventConstants,convertCamelToSnake(event_class_name[:-5],False))) self._ioKeyboard=kbDevice self._ioKeyboard._addEventListener(self,eventIDs) else: ioHub.print2err("Warning: Tobii Cal GFX could not connect to Keyboard device for events.")
def enableEventReporting(self, enable): try: current = self.isReportingEvents() if current == enable: return enable if AnalogInputDevice.enableEventReporting(self, enable) is True: self._scan_count=0 self._data_streaming_thread.enableDataStreaming(True) else: self._data_streaming_thread.enableDataStreaming(False) except: ioHub.print2err("----- LabJack AnalogInput enableEventReporting ERROR ----") ioHub.printExceptionDetailsToStdErr() ioHub.print2err("---------------------------------------------------------")
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 _scanningPoll(self): if self._device_status.value == RUNNING: self._DLL.cbGetStatus (self.device_number, byref(self._device_status), byref(self._samples_received_count), byref(self._current_sample_buffer_index))#,AIFUNCTION) logged_time = currentSec() currentIndex=self._current_sample_buffer_index.value currentSampleCount=self._samples_received_count.value if currentSampleCount > 0 and currentIndex > 0: lastIndex=self._last_sample_buffer_index.value samples=self._local_sample_buffer # ioHub.print2err("cc: %ld\tec: %ld"%(self._samples_received_count.value,self._local_sample_count_created)) # ioHub.print2err("c_index: %ld, l_index: %ld, c_count: %ld"%(currentIndex,lastIndex,currentSampleCount)) if lastIndex != currentIndex: # only for 1208FS #ulStat = self._DLL.cbAConvertData (c_int32(self.device_number), self._current_sample_buffer_index, self._sample_data_buffer,None) self._last_sample_buffer_index=c_long(currentIndex) if lastIndex>currentIndex: for v in xrange(lastIndex,self._input_sample_buffer_size): #ioHub.print2err("v: %d\t%d"%(v,self._sample_data_buffer[v])) self._saveScannedEvent(logged_time,samples,v) lastIndex=0 for v in xrange(lastIndex,currentIndex): #ioHub.print2err("v: %d\t%d"%(v,self._sample_data_buffer[v])) self._saveScannedEvent(logged_time,samples,v) # ioHub.print2err("-----------") else: ioHub.print2err("Error: MC DAQ not responding. Exiting...") self.getConfiguration['_ioServer'].shutDown() sys.exit(1)
def setConnectionState(self,enable): """ """ try: if isinstance(enable,bool): if enable is True and not self.isConnected(): self._eyegaze_control=pEyeGaze.initializeEyeGazeDevice(self._display_device, self.getConfiguration()) if self._eyegaze_control is None: ioHub.print2err("Could not connect to EyeGaze. Exiting app..") sys.exit(0) if self._eyegaze_control: return True return False elif enable is False and self.isConnected(): result=pEyeGaze.EgExit(byref(self._eyegaze_control)) self._eyegaze_control=None return False else: return createErrorResult("INVALID_METHOD_ARGUMENT_VALUE",error_message="The enable arguement value provided is not recognized",method="EyeTracker.setConnectionState",arguement='enable', value=enable) except Exception,e: return createErrorResult("IOHUB_DEVICE_EXCEPTION",error_message="An unhandled exception occurred on the ioHub Server Process.",method="EyeTracker.setConnectionState",arguement='enable', value=enable, error=e)
def pixel2DisplayCoord(cls,px,py): try: dw,dh=cls.getScreenResolution() coordSpace=cls.getDisplayCoordinateType() dx= px-dw/2 dy=-(py-dh/2) if coordSpace == 'pix': return dx,dy elif coordSpace == 'deg': #distH,distV=cls.pixelToDist(swidth/float(pixHres),sheight/float(pixVres),swidth,sheight,px,py) #eyeDist=cls._settings['default_eye_to_calibration_surface_distance']['plane_center'] #r=cls.convertDistToNd(eyeDist,distH,distV) #ioHub.print2stderr(">>>> Pixels x,y to Angle h,v: "+str((px,py))+" : "+str(r)) ioHub.print2err(">>>> UNIMPLEMENTED dispCoordType: "+coordSpace) return 0.0,0.0 else: ioHub.print2err(">>>> UNKNOWN dispCoordType: "+coordSpace) return 0.0,0.0 except Exception, e: ioHub.print2err('ERROR pixel2DisplayCoord: '+str(e)) ioHub.printExceptionDetailsToStdErr() return 0.0,0.0
def displayCoord2Pixel( cls, dx, dy, ): try: dw, dh = cls.getScreenResolution() coordSpace = cls.getDisplayCoordinateType() if coordSpace == 'pix': px = dx + dw / 2 py = (dy + dh / 2) return px, py elif coordSpace == 'deg': ioHub.print2err( ">>>> getDisplayCoordinateType for degrees not implemented yet.: " + coordSpace) return 0.0, 0.0 else: ioHub.print2err(">>>> UNIMPLEMENTED dispCoordType: " + coordSpace) return 0.0, 0.0 except Exception, e: ioHub.print2err('ERROR displayCoord2Pixel: ' + str(e)) ioHub.printExceptionDetailsToStdErr() return 0.0, 0.0
def pixel2DisplayCoord(cls, px, py): try: dw, dh = cls.getScreenResolution() coordSpace = cls.getDisplayCoordinateType() dx = px - dw / 2 dy = -(py - dh / 2) if coordSpace == 'pix': return dx, dy elif coordSpace == 'deg': #distH,distV=cls.pixelToDist(swidth/float(pixHres),sheight/float(pixVres),swidth,sheight,px,py) #eyeDist=cls._settings['default_eye_to_calibration_surface_distance']['plane_center'] #r=cls.convertDistToNd(eyeDist,distH,distV) #ioHub.print2stderr(">>>> Pixels x,y to Angle h,v: "+str((px,py))+" : "+str(r)) ioHub.print2err(">>>> UNIMPLEMENTED dispCoordType: " + coordSpace) return 0.0, 0.0 else: ioHub.print2err(">>>> UNKNOWN dispCoordType: " + coordSpace) return 0.0, 0.0 except Exception, e: ioHub.print2err('ERROR pixel2DisplayCoord: ' + str(e)) ioHub.printExceptionDetailsToStdErr() return 0.0, 0.0
def runSetupProcedure(self,starting_state=EyeTrackerConstants.DEFAULT_SETUP_PROCEDURE): """ runSetupProcedure performs a calibration routine for the Tobii eye tracking system. The current calibration options are relatively limited for the Tobii ioHub interface compared to a standard Tobii calibration procedure. It is hoped that this will be improved in the ioHub Tobii interface as time permits. Result: bool: True if setup / calibration procedue passed, False otherwise. If false, should likely exit experiment. """ try: calibration_properties=self.getConfiguration().get('calibration') circle_attributes=calibration_properties.get('target_attributes') targetForegroundColor=circle_attributes.get('outer_color') # [r,g,b] of outer circle of targets targetBackgroundColor=circle_attributes.get('inner_color') # [r,g,b] of inner circle of targets screenColor=calibration_properties.get('screen_background_color') # [r,g,b] of screen targetOuterDiameter=circle_attributes.get('outer_diameter') # diameter of outer target circle (in px) targetInnerDiameter=circle_attributes.get('inner_diameter') # diameter of inner target circle (in px) genv=TobiiPsychopyCalibrationGraphics(self, targetForegroundColor=targetForegroundColor, targetBackgroundColor=targetBackgroundColor, screenColor=screenColor, targetOuterDiameter=targetOuterDiameter, targetInnerDiameter=targetInnerDiameter) calibrationOK=genv.runCalibration() genv.window.close() genv._unregisterEventMonitors() genv.clearAllEventBuffers() return calibrationOK except: ioHub.print2err("Error during runSetupProcedure") ioHub.printExceptionDetailsToStdErr() return EyeTrackerConstants.EYETRACKER_ERROR
def getPixelsPerDegree(self): """ Returns the Display's horizontal and vertical pixels per degree calculation based on the physical Display settings provided by the monitor in the device's configuration file settings and the resolution of the Display reported by the OS. Args: None Returns: tuple: (ppd_x, ppd_y) given the monitors current resolution and the physical settings provided in the device's configuration file. """ try: return self.getConfiguration()['runtime_info']['pixels_per_degree'] except Exception: ioHub.print2err("ERROR GETTING PPD !") ioHub.printExceptionDetailsToStdErr() return ioHub.server.createErrorResult("DEVICE_ATTRIBUTE_ERROR", error_message="An error occurred while calling a display \ instances getPixelsPerDegree() method.", method="Display.getPixelsPerDegree")
def processevents(self, reply): logged_time=getTime() if reply.category != record.FromServer: return if reply.client_swapped: ioHub.print2err("pyXlib: * received swapped protocol data, cowardly ignored") return if not len(reply.data) or ord(reply.data[0]) < 2: # not an event return data = reply.data while len(data): event, data = rq.EventField(None).parse_binary_value(data, self.record_dpy.display, None, None) event.iohub_logged_time=logged_time if event.type == X.KeyPress: hookevent = self.keypressevent(event) self.KeyDown(hookevent) elif event.type == X.KeyRelease: hookevent = self.keyreleaseevent(event) self.KeyUp(hookevent) elif event.type == X.ButtonPress: hookevent = self.buttonpressevent(event) self.MouseAllButtonsDown(hookevent) elif event.type == X.ButtonRelease and event.detail not in (4,5): # 1 mouse wheel scroll event was generating a button press # and a button release event for each single scroll, so allow # wheel scroll events through for buttonpressevent, but not for # buttonreleaseevent so 1 scroll action causes 1 scroll event. hookevent = self.buttonreleaseevent(event) self.MouseAllButtonsUp(hookevent) elif event.type == X.MotionNotify: # use mouse moves to record mouse position, since press and release events # do not give mouse position info (event.root_x and event.root_y have # bogus info). hookevent=self.mousemoveevent(event) self.MouseAllMotion(hookevent)
def __init__(self,*args,**kwargs): ioHubKeyboardDevice.__init__(self,*args,**kwargs['dconfig']) # TODO: This dict should be reset whenever monitoring is turned off for the device OR # whenever events are cleared fpr the device. # Same to do for the _active_modifiers bool lookup array self._last_general_mod_states=dict(shift_on=False,alt_on=False,cmd_on=False,ctrl_on=False) self._loop_source=None self._tap=None self._device_loop=None self._loop_mode=None self._mods_sum=0 self._tap = Qz.CGEventTapCreate( Qz.kCGSessionEventTap, Qz.kCGHeadInsertEventTap, Qz.kCGEventTapOptionDefault, Qz.CGEventMaskBit(Qz.kCGEventKeyDown) | Qz.CGEventMaskBit(Qz.kCGEventKeyUp)| Qz.CGEventMaskBit(Qz.kCGEventFlagsChanged), self._nativeEventCallback, None) stime=getTime() self._CGEventTapEnable=Qz.CGEventTapEnable self._loop_source = Qz.CFMachPortCreateRunLoopSource(None, self._tap, 0) self._device_loop = Qz.CFRunLoopGetCurrent() self._loop_mode=Qz.kCFRunLoopDefaultMode from ioHub.util import NumPyRingBuffer self._ring_buffer=NumPyRingBuffer(100) Qz.CFRunLoopAddSource(self._device_loop, self._loop_source, self._loop_mode) etime=getTime() print2err("Quartz Tap setup time: ",etime-stime)
def sendResponse(self,data,address): packet_data=None try: max_size=client.MAX_PACKET_SIZE/2-20 packet_data=self.pack(data)+'\r\n' packet_data_length=len(packet_data) if packet_data_length>= max_size: num_packets=len(packet_data)/max_size+1 self.sendResponse(('IOHUB_MULTIPACKET_RESPONSE',num_packets),address) for p in xrange(num_packets-1): self.socket.sendto(packet_data[p*max_size:(p+1)*max_size],address) self.socket.sendto(packet_data[(p+1)*max_size:packet_data_length],address) else: self.socket.sendto(packet_data,address) except: ioHub.print2err('Error trying to send data to experiment process:') ioHub.print2err('data length:',len(data)) first_data_element="NO_DATA_AVAILABLE" if data: ioHub.print2err('Data was [{0}]'.format(data)) try: first_data_element=data[0] except: pass packet_data_length=0 if packet_data: packet_data_length=len(packet_data) ioHub.print2err('packet Data length: ',len(packet_data)) ioHub.printExceptionDetailsToStdErr() data=createErrorResult('IOHUB_SERVER_RESPONSE_ERROR', msg="The ioHub Server Failed to send the intended response.", first_data_element=str(first_data_element), packet_data_length=packet_data_length, max_packet_size=max_size) packet_data=self.pack(data)+'\r\n' packet_data_length=len(packet_data) self.socket.sendto(packet_data,address)
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,configFilePath,config): self._running=True self.config=config self.configFilePath=configFilePath ioServer.eventBuffer=deque(maxlen=config['global_event_buffer']) ioServer._logMessageBuffer=deque(maxlen=128) self.emrt_file=None self.devices=[] self.deviceDict={} self.deviceMonitors=[] # start UDP service self.udpService=udpServer(self,':%d'%config['udpPort']) # dataStore setup if 'ioDataStore' in config and config['ioDataStore']['enable'] is True: configFileDir,cfn=os.path.split(self.configFilePath) resultsFilePath=os.path.join(configFileDir,config['ioDataStore']['filepath']) self.createDataStoreFile(config['ioDataStore']['filename']+'.hdf5',resultsFilePath,'a',config['ioDataStore']['storage_type']) # device configuration if len(config['monitor_devices']) > 0: import ioHub.devices as devices #built device list and config from yaml config settings for iodevice in config['monitor_devices']: for _key,deviceConfig in iodevice.iteritems(): try: # build devices to monitor self.log("Creating Device: %s"%deviceConfig['device_class']) dclass=deviceConfig['device_class'] parentModule=devices modulePathTokens=dclass.split('.') for mt in modulePathTokens: DeviceClass=getattr(parentModule,mt) parentModule=DeviceClass deviceInstance=DeviceClass(dconfig=deviceConfig) self.devices.append(deviceInstance) self.deviceDict[deviceConfig['device_class']]=deviceInstance if 'device_timer' in deviceConfig: interval = deviceConfig['device_timer']['interval'] self.log("%s has requested a timer with period %.5f"%(deviceConfig['device_class'], interval)) dPoller=DeviceMonitor(deviceInstance,interval) self.deviceMonitors.append(dPoller) # add event listeners for streaming events if 'streamEvents' in deviceConfig and deviceConfig['streamEvents'] is True: self.log("Online event access is being enabled for: %s"%deviceConfig['device_class']) # add listener for global event queue deviceInstance._addEventListener(self) # add listener for device event queue deviceInstance._addEventListener(deviceInstance) # add event listeners for saving events if (self.emrt_file is not None) and ('saveEvents' in deviceConfig) and (deviceConfig['saveEvents'] is True): self.log("Event saving is being enabled for: %s"%deviceConfig['device_class']) deviceInstance._addEventListener(self.emrt_file) self.log("==============================") except Exception as e: ioHub.print2err("Exception creating device %s: %s. Is device connected?"%(deviceConfig['device_class'],str(e))) #ioHub.printExceptionDetailsToStdErr() self.log("Exception creating device %s: %s"%(deviceConfig['device_class'],str(e))) deviceDict=self.deviceDict iohub=self if ('Mouse' in deviceDict or 'Keyboard' in deviceDict) and computer.system == 'Windows': class pyHookDevice(object): def __init__(self): import pyHook self._hookManager=pyHook.HookManager() if 'Mouse' in deviceDict: self._hookManager.MouseAll = deviceDict['Mouse']._nativeEventCallback if 'Keyboard' in deviceDict: self._hookManager.KeyAll = deviceDict['Keyboard']._nativeEventCallback if 'Mouse' in deviceDict: self._hookManager.HookMouse() if 'Keyboard' in deviceDict: 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() hookMonitor=DeviceMonitor(pyHookDevice(),0.00375) self.deviceMonitors.append(hookMonitor)
def __init__(self, *args, **kwargs): """ EyeTracker class. This class is to be extended by each eye tracker specific implemetation of the pyEyeTrackerInterface. Please review the documentation page for the specific eye tracker model that you are using the pyEyeTrackerInterface with to get the appropriate module path for that eye tracker; for example, if you are using an interface that supports eye trackers developed by EyeTrackingCompanyET, you may initialize the eye tracker object for that manufacturer something similar too : eyeTracker = hub.eyetrackers.EyeTrackingCompanyET.EyeTracker(**kwargs) where hub is the instance of the ioHubClient class that has been created for your experiment. **kwargs are an optional set of named parameters. **If an instance of EyeTracker has already been created, trying to create a second will raise an exception. Either destroy the first instance and then create the new instance, or use the class method EyeTracker.getInstance() to access the existing instance of the eye tracker object.** """ if EyeTracker._INSTANCE is not None: raise ioHub.devices.ioDeviceError( self.__class__.__name__, "EyeTracker object has already been created; only one instance can exist. Delete existing instance before recreating EyeTracker object." ) # >>>> eye tracker config EyeTracker.eyeTrackerConfig = kwargs['dconfig'] #print " #### EyeTracker Configuration #### " #print self.eyeTrackerConfig #print '' # <<<< ## Load quicklink dll EyeTracker._DLL = windll.LoadLibrary( "C:\\Program Files\\EyeTechDS\\QuickLink2_2.5.1.0\\bin\\QuickLink2.dll" ) ioHub.print2err("DLL: ", EyeTracker._DLL) # create Device level class setting dictionary and pass it Device constructor deviceSettings = dict( instance_code=self.eyeTrackerConfig['instance_code'], category_id=ioHub.devices.EventConstants. DEVICE_CATERGORIES['EYE_TRACKER'], type_id=ioHub.devices.EventConstants. DEVICE_TYPES['EYE_TRACKER_DEVICE'], device_class=self.eyeTrackerConfig['device_class'], user_label=self.eyeTrackerConfig['name'], os_device_code='OS_DEV_CODE_NOT_SET', max_event_buffer_length=self. eyeTrackerConfig['event_buffer_length']) Device.__init__(self, **deviceSettings) # set this instance as 'THE' instance of the eye tracker. EyeTracker._INSTANCE = self EyeTracker.DEVICE_START_TIME = 0.0 # >>>> eye tracker setting to config (if possible) runtimeSettings = self.eyeTrackerConfig['runtime_settings'] # >>>> Display / Calibration related information to use for config if possible EyeTracker.displaySettings = self.eyeTrackerConfig['display_settings'] ioHub.print2err("Start createFrameTest") testFrame = createFrameTest() ioHub.print2err(testFrame.PixelData[0:testFrame.Width * testFrame.Height]) ioHub.print2err("End createFrameTest") ioHub.print2err("Done EyeTech Init")