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