Source code for tracker

import os
import ctypes
import time
from os import path, environ
import tempfile


from pypixxlib._libdpx import err,DetectTrackerType, DPxSelectDevice, \
    TPxGetEyePositionDuringCalib, TPxBestPolyGetEyePosition, TPxConvertCoordSysToCartesian, \
    TPxConvertCoordSysToCustom, TPxBestPolyFinishCalibration, DPxUpdateRegCache, \
    DPxReadRamCall, TPxShowOverlay, TPxHideOverlay, TPxSaveToCSV, TPxSetBuff, TPxEnableFreeRun, \
    DPxSetReg16, DPxWriteRegCache, DPxGetReg16, TPxInitialize, TPxSetAwakePictureRequest, \
    TPxUninitialize, TPxSetSleepPictureRequest, TPxDisableMedianFilter, TPxDisableHDR, \
    TPxSaveImages, TPxSaveImageBaseAddr, TPxSaveImageGap, TPxGetCalibrationImagePtr, \
    TPxEnableMedianFilter, TPxSaveCalibration, TPxLoadCalibration, \
    TPxClearDeviceCalibration, DPxGetTime, TPxGetImagePtr, TPxInitializeCalibration, \
    TPxCalibrateTarget, TPxFinalizeCalibration,DPxGetError, DPxClearError, TPxIsDeviceCalibrated, \
    DP3EnableTPxAnalogOut, DP3DisableTPxAnalogOut, eye, TPxIsAwakePictureRequest, \
    TPxDisableSearchLimits, TPxEnableSearchLimits, TPxSetSearchLimits, TPxGetPupilsCenter, \
    DP3SetVidConsoleDisplay, TPxEnableHDR, TPxSetDistance, TPxGetDistance, TPxGetLens, TPxSetLens, \
    TPxGetPixelDensity,TPxGetLEDIntensity, TPxSetLEDIntensity, TPxGetIrisExpectedSize, \
    TPxSetIrisExpectedSize, TPxPpSizeCalibrationGetEyeData, TPxPpSizeCalibrationDoneGatheringData, \
    TPxPpSizeCalibrationLinearRegression, TPxPpSizeCalibrationClear, TPxIsPpSizeCalibrated, \
    TPxIsRemoteCalibrated, DP3GetVidConsoleMode, TPxMiniSetScreenProportion, TPxSetAllDACOutput, \
    TPxSetTrackerWindowBrightness, TPxSetFixationSamples, TPxSetFixationSpeed, TPxSetSaccadeSamples, \
    TPxSetSaccadeSpeed, TPxGetAllDACOutput, TPxIsSubjectFixating, TPxSetupSchedule, TPxIsSubjectMakingSaccade, \
    TPxGetStatus, TPxStartSchedule, TPxStopSchedule, TPxReadData, TPxTrackingMode, TPxSpecies
     
import png

from pypixxlib.dpxDevice import DpxDevice, DpxExceptionDecorate
#from dpxDevice import DeviceStatusCommunication

[docs]class Tracker(object): """ This class is the bridge between C commands that access device and python commands. When you initiate a new device Access object, all functions are loaded from a .DLL file, and the appropriate C types conversion happen. After that, new functions are created with more Pythonic names that handle the calling of C functions. """ lens = 0 distance = 0 imageWidth = 0 imageHeight = 0 _trackerType = {"TPX3" : 0, "TPXMINI": 1 } _gazePointFilterMode = {\ "QL_DEVICE_GAZE_POINT_FILTER_NONE" : 0,\ "QL_DEVICE_GAZE_POINT_FILTER_MEDIAN_FRAMES": 1, \ "QL_DEVICE_GAZE_POINT_FILTER_MEDIAN_TIME": 2, \ "QL_DEVICE_GAZE_POINT_FILTER_HEURISTIC_FRAMES": 3, \ "QL_DEVICE_GAZE_POINT_FILTER_HEURISTIC_TIME": 4, \ "QL_DEVICE_GAZE_POINT_FILTER_WEIGHTED_PREVIOUS_FRAME": 5, \ "QL_DEVICE_GAZE_POINT_FILTER_MEAN_FRAMES": 6, \ "QL_DEVICE_GAZE_POINT_FILTER_MEAN_TIME": 7 \ } """ QL_DEVICE_GAZE_POINT_FILTER_NONE No gaze point filtering will be done. QL_DEVICE_GAZE_POINT_FILTER_MEDIAN_FRAMES The median gaze point value over the last X number of frames, where X equals the value represented by the setting QL_SETTING_DEVICE_GAZE_POINT_FILTER_VALUE. This will produce a gaze point latency time of about (X / fps / 2) seconds. QL_DEVICE_GAZE_POINT_FILTER_MEDIAN_TIME The median gaze point value over the last X number of frames, where X is the number of frames gathered over twice the amount of milliseconds represented by the setting QL_SETTING_DEVICE_GAZE_POINT_FILTER_VALUE. This will produce a latency of about QL_SETTING_DEVICE_GAZE_POINT_FILTER_VALUE milliseconds. QL_DEVICE_GAZE_POINT_FILTER_HEURISTIC_FRAMES The heuristic filter uses different filtering strengths when the eye is moving and when it is fixating. When the eye is moving, very little filtering is done which results in very low latency. When the eye is fixating, large amounts of filtering are being done which greatly reduce the amount of jitter. Durring fixation, filtering is done over the last X number of frames where X equals the value represented by the setting QL_SETTING_DEVICE_GAZE_POINT_FILTER_VALUE. QL_DEVICE_GAZE_POINT_FILTER_HEURISTIC_TIME The heuristic filter uses different filtering strengths when the eye is moving and when it is fixating. When the eye is moving, very little filtering is done which results in very low latency. When the eye is fixating, large amounts of filtering are being done which greatly reduce the amount of jitter. Durring fixation, filtering is done over the last X number of frames where X equals the number of frames gathered over twice the amount of milliseconds represented by the setting QL_SETTING_DEVICE_GAZE_POINT_FILTER_VALUE. This produces aproximatly the same amount of latency durring fixation for all frame rates. QL_DEVICE_GAZE_POINT_FILTER_WEIGHTED_PREVIOUS_FRAME The weighted previous frame mode filters the gaze point by summing the current weighted gaze point location and the previous weighted gazepoint location. The weights are based on the distance the current gaze point is away from the previous gaze point. The larger the distance, the greater the weight on the current gaze point. The smaller the distance, the greater the weight on the previous gaze point. This results in very low latency when the eye is moving and very low jitter when the eye is fixating. The value represented by the setting QL_SETTING_DEVICE_GAZE_POINT_FILTER_VALUE affects the rate at which the weighting changes from the previous gaze point to the current gaze point. Possible values range between 0 and 200. QL_DEVICE_GAZE_POINT_FILTER_MEAN_FRAMES The mean gaze point value over the last X number of frames, where X equals the value represented by the setting QL_SETTING_DEVICE_GAZE_POINT_FILTER_VALUE. QL_DEVICE_GAZE_POINT_FILTER_MEAN_TIME The mean gaze point value over the last X number of frames, where X is the number of frames gathered over the amount of milliseconds represented by the setting QL_SETTING_DEVICE_GAZE_POINT_FILTER_VALUE. """ analogOutState = {'LEFT_EYE': 0, 'RIGHT_EYE': 1, 'BOTH': 2, 'OFF': -1 }
[docs] @classmethod def buildTrackerObject(self, cls): """Return a specific object on the detected tracker""" if(DetectTrackerType() == cls._trackerType["TPX3"]): return TRACKPixx3() elif (DetectTrackerType() == cls._trackerType["TPXMINI"]): return TRACKPixxMini() else : return self
[docs] def showOverlay(self, presetDisposition = 'FULL_STIMULI_HALF_TRACK'): """Activate Datapixx3 Overlay to display the eye image and eye cursors on monitor.""" pass
[docs] def hideOverlay(self): """Desactivate Datapixx3 Overlay to display the eye image and eye cursors on monitor.""" pass
[docs] def saveBufferedData(self): """Save from last_read_address up to TPxGetReadAddr(), into the default file for today.""" pass
[docs] def setUpDataRecording(self, saveFolder): """Set up the the base address and buffer size for schedule recording of TRACKPixx data.""" pass
[docs] def setLEDintensity(self, led_intensity): """Set the len intensity of the IR led connected to the camera tracker. Args: led_intensity (int): Value of the intensity between 1 to 8. """ pass
[docs] def getLEDintensity(self): """Get the len intensity of the IR led connected to the camera tracker. Returns: int: Value of the intensity between 1 to 8. """ pass return 0
[docs] def setIrisSize(self, lens, dist = 0): """Set the iris size depending of lens type and distance Args: lens (int): Diameter of the len in millimeter (25, 50,75). dist (int): Distance between the camera and the observer. """ pass
[docs] def open(self): """Opens a TrackPixx device. This method is used to get a handle on a TrackPixx device. """ pass
[docs] def setSleepMode(self, enable): """Enables or disables the sleep mode. Enabling this mode turns the TRACKPixx off. Disabling it will turn the TRACKPixx on. Args: enable (bool): Set to true to enable sleep mode. """ pass
[docs] def isSleepMode(self): """Returns True if TRACKPixx sleep mode is enabled. """ pass
[docs] def close(self): """Closes a TrackPixx device. This method is used to release a handle on a TrackPixx device. """ pass
[docs] def getImagePtr(self): """Allocates memory for the image data to be stored in ram and return a int pointing to it.""" pass
[docs] @DpxExceptionDecorate def setScreenProportionToCalibrate(self, proportion): """Set the proportion of the screen to calibrate (TRACKPixx-mini only)""" pass
def getTargetCalibrationImages(self, fileNamePrefix, path, disableMedianFilter, disableHDR): pass
[docs] def initializeBuiltInCalibration(self): """Initialize the built-in calibration (TRACKPixx-mini only)""" pass
[docs] def calibrateBuiltInTarget(self,targetIndex): """"Calibrate a target with built-in calibration (TRACKPixx-mini only). Args: targetIndex (int): Index of the target to calibrate. """ pass
[docs] def finalizeBuiltInCalibration(self): """Finalize the built-in calibration (TRACKPixx-mini only) Returns: int: Retrun 0 if the calibration is finished properly. """ pass
[docs] def saveCalibration(self): """Save last executed calibration to tracker""" pass
[docs] def loadCalibration(self): """Load calibration saved to tracker""" pass
[docs] def clearDeviceCalibration(self): """Clear calibration from tracker, making device not calibrated""" pass
[docs] def getEyePositionDuringCalib(self, x_screen, y_screen, eye_to_verify): """ Tells the camera to get eye position now. This function is to be called during calibration, when there is a focus point displayed on the stimulus display. Args: x_screen (float): x-coordinate of the stimulus y_screen (float): y-coordinate of the stimulus Note: You (will be able to soon) to call this soon after stimulus is displayed (~500 ms after) since the tracker will wait for a fixation itself. """ pass
[docs] def isDeviceCalibrated(self): """ Returns the calibrated state of the tracker. Returns: True when tracked has been successfully calibrated, false otherwise. """ return False
def setAnalogOutState(self, state): pass def getAnalogOutState(self, state): pass def enableSearchLimits(self, enable): pass def setSearchLimits(self, left_X_min, left_Y_min, left_X_max, left_Y_max, right_X_min, right_Y_min, right_X_max, right_Y_max): pass def getPupilsCenter(self): pass
[docs] def setEyePositionToPROPIxx(self, eye_x_final, eye_y_final): """Provide the position of eyes to the PROPIXX """ pass
[docs] def getEyePosition(self): """ Returns the current gaze position by finding the best polynomial. This returns the current calibrated gaze position on the screen using the calibration parameters found for the latest calibration. Returns: A list of gaze position, such that first elements are screen_x_left_eye, screen_y_left_eye, screen_x_right_eye, screen_y_right_eye """ pass
[docs] def convertCoordSysToCartesian(self,inList): """Convert custom coordinate to system coordinate. Args: inList (List): List of coordinates to convert. Returns: (List): List of coordinates to converted. """ return TPxConvertCoordSysToCartesian(inList)
[docs] def convertCoordSysToCustom(self,inList): """Convert custom coordinate to system coordinate. Args: inList (List): List of coordinates to convert. Returns: (List): List of coordinates to converted. """ return TPxConvertCoordSysToCustom(inList)
[docs] def finishCalibration(self): """Finishes the calibration on the Device. This function is to be called when you are done displaying stimuli for calibration. It will calculate the calibrations parameter on the device and set the state to calibrated (which can be verified through ``isDeviceCalibrated``. """ pass
[docs] def getTime(self): """Gets the device time from DataPixx since power up. Returns: float: Time in seconds. """ pass
[docs] def setActive(self): """Use to fake calls on dpxDevice""" pass
[docs] def updateRegisterCache(self): """Use to fake calls on dpxDevice""" pass
[docs] def setDistance(self, distance): """ Sets the current setup tracking distance in cm. This is used along with lens to determine the iris size. """ pass
[docs] def getDistance(self): """ Returns the tracking distance in cm. This returns the current distance set in tracker in cm. This is used along with lens to determine the iris size. Returns: The distance in cm """ return 0
[docs] def getLens(self): """Returns the lens type currently selected. Lens can take three different values: - 0 (25mm) - 1 (50mm) - 2 (75mm) """ pass
[docs] def setLens(self, lens): """ Sets the lens specified to Datapixx3. This will have an impact on camera object image size calculation. Lens can take three different values: - 0 (25mm) - 1 (50mm) - 2 (75mm) """ pass
def updateIrisSize(self): pass def getIrisSize(self): return 0 # because this is an int return function. pass def ppSizeCalGetEyeData(self): pass def ppSizeCalDoneGatheringData(self): pass def ppSizeCalLinearRegression(self): pass def ppSizeCalClear(self): pass def isPpSizeCalibrated(self): return False def setSaccadeSpeed(self): pass def setSaccadeSamples(self): pass def setFixationSpeed(self): pass def setFixationSamples(self): pass def setTrackingMode(self): pass def setTrackingSpecies(self): pass
[docs]class TRACKPixx3(Tracker,DpxDevice): """ Class Definition for the DATAPixx3 Device. The bases defined below are the core subsystems attached to a DATAPixx3 devices. A DATAPixx3 device also has very specific subsystems which are used through handles. See the example bellow for more details. Note: If you have a **Lite** version of the device, some of these handles will not be available. The usage of the handles is as follows: >>> from pypixxlib.datapixx import DATAPixx3 >>> my_device = DATAPixx3() >>> my_device.adc.function() # adc is the subsystem in this example. >>> my_device.BaseFunction() # A base function from one of the class' bases. """ def __init__(self): super(TRACKPixx3, self).__init__('TRACKPixx') self.devsel = 70 DPxUpdateRegCache() self.subsystems = ['General'] #self.device_comm = DeviceStatusCommunication() self.connected = False self.address = 0x75EEC000 self.length = 1280 * 512 self.int_list = [0] * self.length self.int_size = ctypes.sizeof(ctypes.c_ushort) self.item_count = len(self.int_list) self.total_size = self.int_size * self.item_count self.packed_data = (ctypes.c_ushort * self.item_count)(*self.int_list) self.deviceRegistered = True self.eye_to_verify = 3 self.fileName = "" # Buffer DAta self.buffer_base_addr = 0x12000000 self.buffer_size = 0x18000000 self.last_read_addr = self.buffer_base_addr self.subsystems = ['General'] self.tempDir = os.path.join(tempfile.gettempdir(),"VPixx") if not os.path.exists(self.tempDir): os.makedirs(self.tempDir)
[docs] @DpxExceptionDecorate def setSleepMode(self, enable): if (enable): TPxSetSleepPictureRequest() else : TPxSetAwakePictureRequest() DPxUpdateRegCache()
[docs] @DpxExceptionDecorate def isSleepMode(self): return not TPxIsAwakePictureRequest()
[docs] @DpxExceptionDecorate def showOverlay(self, presetDisposition = 'FULL_STIMULI_HALF_TRACK'): DP3SetVidConsoleDisplay(presetDisposition) DPxUpdateRegCache()
[docs] @DpxExceptionDecorate def hideOverlay(self): DP3SetVidConsoleDisplay('FULL_STIMULI_NO_TRACK') DPxUpdateRegCache()
@DpxExceptionDecorate def getVideoConsoleDisplayMode(self): DPxUpdateRegCache() return DP3GetVidConsoleMode()
[docs] @DpxExceptionDecorate def saveBufferedData(self): print("Recording data is not yet directly implemented in the TRACKPixx3 -- Please use the schedule method") p = ctypes.create_string_buffer(self.fileName.encode('utf-8')) self.last_read_addr = TPxSaveToCSV(self.last_read_addr, p)
[docs] @DpxExceptionDecorate def setUpDataRecording(self, saveFolder): print("Recording data is not yet directly implemented in the TRACKPixx3 -- Please use the schedule method") self.fileName = path.join(saveFolder, 'data') if not os.path.exists(self.fileName): os.makedirs(self.fileName) self.fileName = path.join(self.fileName, 'TPx_%s.csv' % str(time.strftime("%Y-%m-%d_%H-%M-%S"))) TPxSetBuff(self.buffer_base_addr, self.buffer_size) self.last_read_addr = self.buffer_base_addr TPxEnableFreeRun() DPxUpdateRegCache() return self.fileName
[docs] @DpxExceptionDecorate def setLEDintensity(self, led_intensity): TPxSetLEDIntensity(led_intensity) DPxUpdateRegCache()
[docs] @DpxExceptionDecorate def getLEDintensity(self): DPxUpdateRegCache() return TPxGetLEDIntensity()
[docs] @DpxExceptionDecorate def setIrisSize(self, lens, dist = 0): if (lens > 2): lens = TPxGetLens(); self.__class__.lens = lens TPxSetLens(lens) if dist == 0: # Get from device dist = TPxGetDistance() # this is in mm. else: TPxSetDistance(dist) #dist = dist * 10 # convert to mm # This wil be changed in the future for more user-friendly calculations if (lens == 0): irisWidth = (12.0 * 1280.0 / (0.33475 * dist + 8.6350)) elif (lens == 1): irisWidth = (12.0 * 1280.0 / (0.16661 * dist - 2.5458)) elif (lens == 2): irisWidth = (12.0 * 1280.0 / (0.11177 * dist - 4.2935)) TPxSetIrisExpectedSize(int(irisWidth)); DPxUpdateRegCache()
[docs] @DpxExceptionDecorate def open(self): DpxDevice.__init__(self,'TRACKPIXX') DPxUpdateRegCache() #Initialyze and select tracker as TPX3 TPxInitialize(super(TRACKPixx3, self)._gazePointFilterMode["QL_DEVICE_GAZE_POINT_FILTER_NONE"]) TPxHideOverlay() TPxSetAwakePictureRequest() DPxUpdateRegCache() self.connected = True
[docs] @DpxExceptionDecorate def close(self): #mask error il tpx is not open before try: TPxUninitialize() TPxSetSleepPictureRequest() DPxUpdateRegCache() DpxDevice.close(self) self.connected = False finally: DPxClearError()
[docs] @DpxExceptionDecorate def getImagePtr(self): self.packed_data, self.imageHeight, self.imageWidth = TPxGetImagePtr() return self.packed_data
[docs] @DpxExceptionDecorate def setScreenProportionToCalibrate(self, proportion): pass
[docs] @DpxExceptionDecorate def getTargetCalibrationImages(self, fileNamePrefix, path, disableMedianFilter, disableHDR): """ Save 16 frames images in the png format to disk """ frameCount = 16 length = 1280 * 512 int_list = [0] * length item_count = len(int_list) packed_data = (ctypes.c_ushort * item_count)(*int_list) disableMedianPrefix = "" disableHDRPrefix = "" if (disableMedianFilter): TPxDisableMedianFilter() DPxUpdateRegCache() disableMedianPrefix = "_MED0" if (disableHDR): TPxDisableHDR() DPxUpdateRegCache() disableHDRPrefix = "_HDR0" TPxSaveImages() images = [] imageFilePaths = [] for frameIndex in range(0,frameCount): packed_data, imageHeight, imageWidth = TPxGetCalibrationImagePtr(frameIndex) imageFileName = '%s%s%s_Frm%02d.png' % (fileNamePrefix,disableMedianPrefix,disableHDRPrefix,frameIndex+1) imageFilePath = os.path.join(path,imageFileName) images.append(packed_data) imageFilePaths.append(imageFilePath) TPxEnableMedianFilter() TPxEnableHDR() DPxUpdateRegCache() return images,imageFilePaths, imageHeight, imageWidth
[docs] @DpxExceptionDecorate def saveCalibration(self): TPxSaveCalibration()
[docs] @DpxExceptionDecorate def loadCalibration(self): TPxLoadCalibration()
[docs] @DpxExceptionDecorate def clearDeviceCalibration(self): TPxClearDeviceCalibration() DPxUpdateRegCache()
[docs] @DpxExceptionDecorate def setEyePositionToPROPIxx(self, eye_x_final, eye_y_final): DPxSelectDevice("PROPIXX") DPxSetReg16(ctypes.c_uint(0x1BC), ctypes.c_uint(int(eye_x_final))) DPxSetReg16(ctypes.c_uint(0x1BE), ctypes.c_uint(1080-int(eye_y_final))) DPxUpdateRegCache() DPxSelectDevice("AUTO")
[docs] @DpxExceptionDecorate def getTime(self): DPxUpdateRegCache() return DPxGetTime()
[docs] @DpxExceptionDecorate def getEyePositionDuringCalib(self, x_screen, y_screen, eye_to_verify): TPxGetEyePositionDuringCalib(ctypes.c_double(x_screen), ctypes.c_double(y_screen), ctypes.c_int(eye_to_verify))
[docs] @DpxExceptionDecorate def getEyePosition(self): length = 4 int_list = [0]*length item_count = len(int_list) int_list2 = [0]*length item_count2 = len(int_list2) packed_data = (ctypes.c_double * item_count)(*int_list) raw_data = (ctypes.c_double * item_count2)(*int_list2) TPxBestPolyGetEyePosition(packed_data, raw_data) return packed_data
[docs] @DpxExceptionDecorate def finishCalibration(self): TPxBestPolyFinishCalibration()
[docs] @DpxExceptionDecorate def isDeviceCalibrated(self): DPxUpdateRegCache() return TPxIsDeviceCalibrated()
@DpxExceptionDecorate def setAnalogOutState(self, state): TPxSetAllDACOutput(state) #if state == self.analogOutState['OFF']: #DP3DisableTPxAnalogOut() # TPxSetAllDACOutput(0) #elif state == self.analogOutState['LEFT_EYE'] : #DP3EnableTPxAnalogOut(eye['LEFT_EYE']) # TPxSetAllDACOutput(1 | 3 << 8 | 5 << 16); #elif state == self.analogOutState['RIGHT_EYE'] : #DP3EnableTPxAnalogOut(eye['RIGHT_EYE']) # TPxSetAllDACOutput(2 | 4 << 8 | 6 << 16); #elif state == self.analogOutState['BOTH'] : #DP3EnableTPxAnalogOut(eye['BOTH']) # TPxSetAllDACOutput(1 | 3 << 8 | 2 << 16 | 4 << 24); @DpxExceptionDecorate def getAnalogOutState(self, state): return TPxGetAllDACOutput() @DpxExceptionDecorate def enableSearchLimits(self, enable): if enable : TPxEnableSearchLimits() else: TPxDisableSearchLimits() DPxUpdateRegCache() @DpxExceptionDecorate def setSearchLimits(self, left_X_min, left_Y_min, left_X_max, left_Y_max, right_X_min, right_Y_min, right_X_max, right_Y_max): TPxSetSearchLimits((left_X_min, left_Y_min, left_X_max, left_Y_max), (right_X_min, right_Y_min, right_X_max, right_Y_max)) DPxUpdateRegCache() @DpxExceptionDecorate def getPupilsCenter(self): DPxUpdateRegCache() return TPxGetPupilsCenter()
[docs] @DpxExceptionDecorate def setDistance(self, distance): TPxSetDistance(distance) DPxUpdateRegCache()
[docs] @DpxExceptionDecorate def getDistance(self): DPxUpdateRegCache() return TPxGetDistance()
[docs] @DpxExceptionDecorate def getLens(self): DPxUpdateRegCache() lens = TPxGetLens() self.__class__.lens = lens return lens
[docs] @DpxExceptionDecorate def setLens(self, lens): self.__class__.lens = lens TPxSetLens(lens) DPxUpdateRegCache()
@DpxExceptionDecorate def updateIrisSize(self): size = int(12 * TPxGetPixelDensity()) TPxSetIrisExpectedSize(size) @DpxExceptionDecorate def getIrisSize(self): DPxUpdateRegCache() return TPxGetIrisExpectedSize() @DpxExceptionDecorate def ppSizeCalGetEyeData(self): TPxPpSizeCalibrationGetEyeData() @DpxExceptionDecorate def ppSizeCalDoneGatheringData(self): TPxPpSizeCalibrationDoneGatheringData() @DpxExceptionDecorate def ppSizeCalLinearRegression(self): TPxPpSizeCalibrationLinearRegression() @DpxExceptionDecorate def ppSizeCalClear(self): TPxPpSizeCalibrationClear() DPxUpdateRegCache() @DpxExceptionDecorate def isPpSizeCalibrated(self): return TPxIsPpSizeCalibrated() @DpxExceptionDecorate def setTrackerWindowBrightness(self, brightness): TPxSetTrackerWindowBrightness(brightness) @DpxExceptionDecorate def setSaccadeSpeed(self, speed): TPxSetSaccadeSpeed(speed) @DpxExceptionDecorate def setSaccadeSamples(self, samples): TPxSetSaccadeSamples(samples) @DpxExceptionDecorate def setFixationSpeed(self, speed): TPxSetFixationSpeed(speed) @DpxExceptionDecorate def setFixationSamples(self, samples): TPxSetFixationSamples(samples) @DpxExceptionDecorate def isSubjectMakingSaccade(self): return TPxIsSubjectMakingSaccade() @DpxExceptionDecorate def isSubjectFixating(self): return TPxIsSubjectFixating() @DpxExceptionDecorate def setupSchedule(self, bufferbaseAddress=int(12e6), numBuffFrames=int(36e5)): return TPxSetupSchedule(bufferbaseAddress, numBuffFrames) @DpxExceptionDecorate def getStatus(self, TPxDict): TPxGetStatus(TPxDict) @DpxExceptionDecorate def startSchedule(self): TPxStartSchedule() @DpxExceptionDecorate def stopSchedule(self): TPxStopSchedule() @DpxExceptionDecorate def readData(self, TPxDict, numFrames = None): TPxReadData(TPxDict, numFrames) @DpxExceptionDecorate def setTrackingMode(self, mode): TPxTrackingMode(1, mode) @DpxExceptionDecorate def setSpecies(self, species): TPxSpecies(1, species)
[docs]class TRACKPixxMini(Tracker): """ This class is the concrete class specific to TRACKPixx-mini Tracker only . """ def __init__(self): self.length = 680 * 358 self.int_list = [0] * self.length self.int_size = ctypes.sizeof(ctypes.c_uint) self.item_count = len(self.int_list) self.total_size = self.int_size * self.item_count self.packed_data = (ctypes.c_ushort * self.item_count)(*self.int_list) self.deviceRegistered = False self.subsystems = ['General'] self.name = 'TRACKPixx /mini' self.device_type = 'TRACKPixx /mini' self.identification = 'TRACKPixx /mini' self.firmware_revision = 1 self.id_number = 0 self.tempDir = os.path.join(tempfile.gettempdir(),"VPixx") if not os.path.exists(self.tempDir): os.makedirs(self.tempDir)
[docs] @DpxExceptionDecorate def open(self,licenseFileDir = ''): if not self.deviceRegistered: if (licenseFileDir == ''): licenseFileDir = path.join(environ['PROGRAMDATA'],'VPixx Technologies') licenseFileDir = path.join(licenseFileDir,'Licenses') licenseFileDir = path.join(licenseFileDir,'TRACKPIxx-mini.lic') #Initialyze and select tracker as TPX3 TPxInitialize(super(TRACKPixxMini, self)._gazePointFilterMode["QL_DEVICE_GAZE_POINT_FILTER_NONE"], licenseFileDir) dpxError = DPxGetError() if dpxError == 'DPX_SUCCESS': self.deviceRegistered = True elif dpxError == 'DPX_ERR_TRK_QL_DEVICE_IS_NOT_REGISTERED': self.deviceRegistered = False DPxClearError() else: self.deviceRegistered = False
[docs] @DpxExceptionDecorate def close(self): TPxUninitialize() self.deviceRegistered = False
[docs] @DpxExceptionDecorate def getImagePtr(self): self.packed_data, self.imageHeight, self.imageWidth = TPxGetImagePtr() return self.packed_data
[docs] @DpxExceptionDecorate def setScreenProportionToCalibrate(self, proportion): TPxMiniSetScreenProportion(proportion)
@DpxExceptionDecorate def initializeCalibration(self): return TPxInitializeCalibration() @DpxExceptionDecorate def calibrateTarget(self,targetIndex): TPxCalibrateTarget(targetIndex) @DpxExceptionDecorate def finalizeCalibration(self): return TPxFinalizeCalibration()
[docs] def getName(self): """Return part number""" return "TRACKPixx-mini"
[docs] @DpxExceptionDecorate def getEyePositionDuringCalib(self, x_screen, y_screen, eye_to_verify): pass
[docs] @DpxExceptionDecorate def getEyePosition(self): length = 4 int_list = [0]*length item_count = len(int_list) int_list2 = [0]*length item_count2 = len(int_list2) packed_data = (ctypes.c_double * item_count)(*int_list) raw_data = (ctypes.c_double * item_count2)(*int_list2) TPxBestPolyGetEyePosition(packed_data, raw_data) return packed_data
[docs] @DpxExceptionDecorate def finishCalibration(self): pass
[docs] @DpxExceptionDecorate def isDeviceCalibrated(self): return TPxIsRemoteCalibrated()
[docs] def saveBufferedData(self): p = ctypes.create_string_buffer(self.fileName.encode('utf-8')) TPxSaveToCSV(0, p)
[docs] @DpxExceptionDecorate def setUpDataRecording(self, saveFolder): self.fileName = path.join(saveFolder, 'data') if not os.path.exists(self.fileName): os.makedirs(self.fileName) self.fileName = path.join(self.fileName, 'TPx_mini_%s.csv' % str(time.strftime("%Y-%m-%d_%H-%M-%S"))) return self.fileName
@DpxExceptionDecorate def getPupilsCenter(self): return TPxGetPupilsCenter()