def eyeConfig(self): #Establish a connection to the eyetracker if not dummyMode: tk = pylink.EyeLink('100.1.1.1') self.eyeTracker = eyeConfig.eyetrackersetup(tk, self.monitor) #Not calibration, eye_tracker = tk eyeConfig.eyeCalibration(dummyMode, self.eyeTracker, self.monitor) #Calibration self.eyeTracker.openDataFile(self.edfFile) else: tk = pylink.EyeLink(None) self.eyeTracker = tk
def __init__(self, win, fileName, folderName, dummy=False): self.win = win self.text = visual.TextStim(self.win, text="hello") if dummy == False: self.tk = pylink.EyeLink("100.1.1.1") else: self.tk = pylink.EyeLink(None) self.dataFileName = fileName self.dataFolderName = folderName genv = EyeLinkCoreGraphicsPsychoPy(self.tk, win) pylink.openGraphicsEx(genv)
def __init__(self, window, edfname): # Pull out monitor info self.sres = window.size self.scenter = [self.sres[0] / 2.0, self.sres[1] / 2.0] self.win = window # Make filename fname = os.path.splitext(edfname)[0] # strip away extension if present assert re.match(r'\w+$', fname), 'Name must only include A-Z, 0-9, or _' assert len(fname) <= 8, 'Name must be <= 8 characters.' self.edfname = fname + '.edf' # Initialize connection with eyetracker try: self.tracker = pylink.EyeLink() self.realconnect = True except RuntimeError: self.tracker = pylink.EyeLink(None) self.realconnect = False # Check which eye is being recorded self.eye_used = self.tracker.eyeAvailable() # Make pylink accessible self.pylink = pylink # Open EDF self.tracker.openDataFile(self.edfname) pylink.flushGetkeyQueue() self.tracker.setOfflineMode() # Set content of edf file self.tracker.sendCommand( 'file_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,MESSAGE,BUTTON,INPUT' ) self.tracker.sendCommand( 'link_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,BUTTON') self.tracker.sendCommand( 'link_sample_data = LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS,HTARGET') self.tracker.sendCommand( 'file_sample_data = LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS,HTARGET,INPUT' ) # Set display coords for dataviewer self.tracker.sendMessage("screen_pixel_coords = 0 0 %d %d" % (x_size - 1, y_size - 1)) self.tracker.sendMessage("DISPLAY_COORDS 0 0 %d %d" % (x_size - 1, y_size - 1))
def __init__(self, window, edfname, address="100.1.1.1"): # Pull out monitor info self.sres = window.size self.scenter = [self.sres[0] / 2.0, self.sres[1] / 2.0] self.win = window # Make filename fname = os.path.splitext(edfname)[0] # strip away extension if present assert re.match(r'\w+$', fname), 'Name must only include A-Z, 0-9, or _' assert len(fname) <= 8, 'Name must be <= 8 characters.' self.edfname = fname + '.edf' # Initialize connection with eye-tracker try: self.tracker = pylink.EyeLink(address) self.realconnect = True except RuntimeError: self.tracker = pylink.EyeLink(None) self.realconnect = False # Make pylink accessible self.pylink = pylink # Open EDF #Close any open file first if self.tracker.getTrackerMode() == pylink.EL_RECORD_MODE: self.tracker.closeDataFile() self.tracker.openDataFile(self.edfname) pylink.flushGetkeyQueue() self.tracker.setOfflineMode() # Set content of edf file eftxt = 'LEFT,RIGHT,FIXATION,SACCADE,BLINK,MESSAGE,BUTTON,INPUT' self.tracker.sendCommand('file_event_filter = ' + eftxt) lftxt = 'LEFT,RIGHT,FIXATION,SACCADE,BLINK,BUTTON' self.tracker.sendCommand('link_event_filter = ' + lftxt) lstxt = 'LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS,HTARGET' self.tracker.sendCommand('link_sample_data = ' + lstxt) fstxt = 'LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS,HTARGET,INPUT' self.tracker.sendCommand('file_sample_data = ' + fstxt) # Set display coords for dataviewer disptxt = 'DISPLAY_COORDS 0 0 {} {}'.format(*self.sres) self.tracker.sendMessage(disptxt) # Check which eye is being recorded self.eye_used = self.tracker.eyeAvailable()
def __init__(self, window, filename, eye): if len(filename) > 12: raise ValueError( 'EDF filename must be at most 12 characters long including the extension.' ) if filename[-4:] != '.edf': raise ValueError( 'Please include the .edf extension in the filename.') if eye not in ('LEFT', 'RIGHT', 'BOTH'): raise ValueError('eye must be set to LEFT, RIGHT, or BOTH.') self.window = window self.edf_filename = filename self.edf_open = False self.eye = eye self.resolution = tuple(window.size) self.tracker = pl.EyeLink() self.genv = PsychoPyCustomDisplay(self.window, self.tracker) if all(i >= 0.5 for i in self.window.color): self.text_color = (-1, -1, -1) else: self.text_color = (1, 1, 1)
def _setup_eyelink(win_size): """set up the eyelink eye-tracking """ # Connect to eyelink eyetracker = pylink.EyeLink('192.168.1.5') pylink.openGraphics() # Set content of edf file eyetracker.sendCommand('link_sample_data=LEFT,RIGHT,GAZE,AREA') eyetracker.sendCommand( 'file_sample_data=LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS') eyetracker.sendCommand( 'file_event_filter=LEFT,RIGHT,FIXATION,SACCADE,BLINK,MESSAGE,BUTTON') # Set coords eyetracker.sendCommand('screen_pixel_coords=0 0 {} {}'.format(*win_size)) eyetracker.sendMessage('DISPLAY_COORDS 0 0 {} {}'.format(*win_size)) # Calibrate eyetracker.setCalibrationType('HV5') eyetracker.doTrackerSetup(win_size) pylink.closeGraphics() return eyetracker
def _trackerCreate(self): """Helper method not directly called in EyeScript scripts in general configures the Eyelink eyetracker """ try: self.tracker = pylink.EyeLink() except (RuntimeError,AttributeError): self.tracker = EyetrackerStub() #This tells the tracker to use VisionEgg to display Eyelink graphics #including calibration points, camera images, etc. self.eyelinkGraphics = EyeLinkCoreGraphicsVE(self.screen,self.tracker) pylink.openGraphicsEx(self.eyelinkGraphics) self.eyelinkGraphics.setCalibrationColors(self['color'],self['bgcolor']) for key,value in self.iteritems(): command = key.split('_',1) if len(command) > 1 and command[0] == 'tracker': getattr(self.tracker,command[1])(value) if self['heuristic_filter'] == 'off': self.tracker.setHeuristicFilterOff() else: self.tracker.setHeuristicFilterOn() #Set whether beeps should be played during drift correction pylink.setDriftCorrectSounds(*self['setDriftCorrectSounds']) # open the datafile on the operator pc if self['subject'] > 0: self.tracker.openDataFile(self.edffile) self.tracker.sendCommand("screen_pixel_coords = 0 0 %d %d"%(self['screen_size']))
def _try_connection(): """Attempts to connect to eyetracker. Returns a bool indicating if a connection was made and an exception if applicable. If there's no exeception, the second return value will be None. """ print('Attempting to connect to eye tracker...') try: pl.EyeLink() return True, None except RuntimeError as e: return False, e
def setup_eyelink(self): '''Thank you very much ''' # call for eyelink self.eyelink_tracker = pl.EyeLink("100.1.1.1") #parameters for eyelink self.monitor = monitors.Monitor('testMonitor') self.winSize = self.monitor.getSizePix() self.foreground = (250,250,250) self.background = (127,127,127) # create file self.edfFileName = "cbConfig" + str(self.subjectID) if len(self.edfFileName) > 8: self.edfFileName = self.edfFileName[0:8] pl.getEYELINK().openDataFile(self.edfFileName) pl.getEYELINK().setOfflineMode() #Eyelink - Gets the display surface and sends a mesage to EDF file; pl.getEYELINK().sendCommand("screen_pixel_coords = 0 0 %d %d"%(self.winSize[0]-1, self.winSize[1]-1)) pl.getEYELINK().sendMessage("Resolution %d %d" %((self.winSize[0]-1, self.winSize[1]-1))) pl.getEYELINK().sendMessage("EyeToScreen %d" %(self.monitor.getDistance())) pl.getEYELINK().sendMessage("MonitorWidth %d" %(self.monitor.getWidth())) #EyeLink - Set data file contents pl.getEYELINK().sendCommand("file_sample_data = LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS,HTARGET,INPUT") pl.getEYELINK().sendCommand("link_sample_data = LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS,HTARGET,INPUT") #EyeLink - Set Filter contents pl.getEYELINK().sendCommand("file_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,MESSAGE,BUTTON,INPUT") pl.getEYELINK().sendCommand("link_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,BUTTON,INPUT") #EyeLink - Set Calibration Environment pl.setCalibrationColors(self.foreground, self.background); #Sets the calibration target and background color - background color should match testing background pl.flushGetkeyQueue() pl.getEYELINK().setOfflineMode() winX = int(self.winSize[0]) winY = int(self.winSize[1]) pl.openGraphics((winX,winY),32) pl.getEYELINK().doTrackerSetup() pl.closeGraphics() pl.setCalibrationSounds("", "", ""); pl.setDriftCorrectSounds("", "off", "off"); # close configuration file event.clearEvents() pl.getEYELINK().closeDataFile() transferFileName = self.edfFileName + '.edf' # fileName pl.getEYELINK().receiveDataFile(self.edfFileName, transferFileName)
def libeyelink(edfname): global realconnect global tracker global edfname # Make filename fname = os.path.splitext(edfname)[0] # strip away extension if present assert re.match(r'\w+$', fname), 'Name must only include A-Z, 0-9, or _' assert len(fname) <= 8, 'Name must be <= 8 characters.' edfname = fname + '.edf' # Initialize connection with eyetracker try: tracker = pylink.EyeLink() realconnect = True except RuntimeError: tracker = pylink.EyeLink(None) realconnect = False # Open EDF pylink.getEYELINK().openDataFile(edfname) pylink.flushGetkeyQueue() pylink.getEYELINK().setOfflineMode() # Set content of edf file pylink.getEYELINK().sendCommand( 'file_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,MESSAGE,BUTTON,INPUT') pylink.getEYELINK().sendCommand( 'link_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,BUTTON') pylink.getEYELINK().sendCommand( 'link_sample_data = LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS,HTARGET') pylink.getEYELINK().sendCommand( 'file_sample_data = LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS,HTARGET,INPUT') # Set display coords for dataviewer pylink.getEYELINK().sendMessage("screen_pixel_coords = 0 0 %d %d" %(w - 1, h - 1)) pylink.getEYELINK().sendMessage("DISPLAY_COORDS 0 0 %d %d" %(w - 1, h - 1))
def __init__(self, window, edfname): # Pull out monitor info self.sres = window.size self.win = window # Make filename self.edfname = edfname + '.edf' # Initialize connection with eye-tracker try: self.tracker = pylink.EyeLink() self.realconnect = True except: self.tracker = pylink.EyeLink(None) self.realconnect = False # Make pylink accessible self.pylink = pylink # Open EDF self.tracker.openDataFile(self.edfname) pylink.flushGetkeyQueue() self.tracker.setOfflineMode() # Set content of edf file eftxt = 'LEFT,RIGHT,FIXATION,SACCADE,BLINK,MESSAGE,BUTTON,INPUT' self.tracker.sendCommand('file_event_filter = ' + eftxt) lftxt = 'LEFT,RIGHT,FIXATION,SACCADE,BLINK,BUTTON' self.tracker.sendCommand('link_event_filter = ' + lftxt) lstxt = 'LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS,HTARGET' self.tracker.sendCommand('link_sample_data = ' + lstxt) fstxt = 'LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS,HTARGET,INPUT' self.tracker.sendCommand('file_sample_data = ' + fstxt) # Set display coords for dataviewer disptxt = 'DISPLAY_COORDS 0 0 {} {}'.format(*self.sres) self.tracker.sendMessage(disptxt)
def _create_tracker(self): """ Creates tracker object upon initialization. """ if not self.eyetracker_on or not PYLINK_AVAILABLE: return None tracker = pylink.EyeLink(self.et_settings.get('address')) pylink.flushGetkeyQueue() tracker.setOfflineMode() tracker.sendCommand('set_idle_mode') # why? self.edf_name = datetime.now().strftime('%H_%M_%S.edf') tracker.openDataFile(self.edf_name) return tracker
def _init_tracker(self): self.tracker = pylink.EyeLink() # Gets the display surface and sends a mesage to EDF file; self.tracker.sendCommand( "screen_pixel_coords = 0 0 %d %d" % self.screenRect.size) self.tracker.sendMessage( "DISPLAY_COORDS 0 0 %d %d" % self.screenRect.size) tracker_software_ver = 0 eyelink_ver = self.tracker.getTrackerVersion() if eyelink_ver == 3: tvstr = self.tracker.getTrackerVersionString() vindex = tvstr.find("EYELINK CL") tracker_software_ver = int(float( tvstr[(vindex + len("EYELINK CL")):].strip())) if eyelink_ver >= 2: self.tracker.sendCommand("select_parser_configuration 0") if eyelink_ver == 2: # turn off scenelink camera stuff self.tracker.sendCommand("scene_camera_gazemap = NO") else: self.tracker.sendCommand("saccade_velocity_threshold = 35") self.tracker.sendCommand( "saccade_acceleration_threshold = 9500") # set EDF file contents self.tracker.sendCommand( "file_event_filter = " + "LEFT,RIGHT,FIXATION,SACCADE,BLINK,MESSAGE,BUTTON") if tracker_software_ver >= 4: self.tracker.sendCommand( "file_sample_data = " + "LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS,HTARGET") else: self.tracker.sendCommand( "file_sample_data = " + "LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS") # set link data (used for gaze cursor) self.tracker.sendCommand( "link_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,BUTTON") if tracker_software_ver >= 4: self.tracker.sendCommand( "link_sample_data = " + "LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS,HTARGET") else: self.tracker.sendCommand( "link_sample_data = " + "LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS") self.tracker.sendCommand("button_function 5 'accept_target_fixation'")
def __init__(self, address='10.0.0.2'): ''' Constructor for the System representing the EyeLink eyetracker Parameters ---------- address: IP address string IP address of the EyeLink host machine Returns ------- System instance ''' self.tracker = pylink.EyeLink(address) self.tracker.setOfflineMode()
def __init__(self, screen_width_px, screen_height_px, dot_size, N_trials, observer, datadir, timeStr): self.eyelinktracker = pylink.EyeLink() self.eyelink = pylink.getEYELINK() self.screen_width_px = screen_width_px self.screen_height_px = screen_height_px self.dot_size = dot_size self.N_trials = N_trials self.mode = 'enregistrement' self.edfFileName = "%s.EDF" % ( observer ) # ne doit pas contenir plus de 8 caractères -- Must contains no more than 8 characters self.edfFileName_2 = os.path.join( datadir, self.mode + '_' + observer + '_' + timeStr + '.edf')
def __init__(self, sp): """ initialize eyetracker @param 'sp' screen res""" el = pl.EyeLink() # pygaze uses # pylink.getEYELINK().setPupilSizeDiameter(True) # pylink.getEYELINK().sendCommand(cmd) el.sendCommand("screen_pixel_coords = 0 0 %d %d" % (sp[0], sp[1])) el.quietMode(0) # allow messages el.sendMessage("DISPLAY_COORDS 0 0 %d %d" % (sp[0], sp[1])) el.sendCommand("select_parser_configuration 0") el.sendCommand("scene_camera_gazemap = NO") # area or diameter el.sendCommand("pupil_size_diameter = YES") self.el = el self.sp = sp
def __init__(self, ec, link='default', fs=1000, verbose=None): if link == 'default': link = get_config('EXPYFUN_EYELINK', None) if link is not None and pylink is None: raise ImportError('Could not import pylink, please ensure it ' 'is installed correctly to use the EyeLink') valid_fs = (250, 500, 1000, 2000) if fs not in valid_fs: raise ValueError('fs must be one of {0}'.format(list(valid_fs))) output_dir = ec._output_dir if output_dir is None: output_dir = os.getcwd() if not isinstance(output_dir, string_types): raise TypeError('output_dir must be a string') if not op.isdir(output_dir): os.mkdir(output_dir) self._output_dir = output_dir self._ec = ec if 'el_id' in self._ec._id_call_dict: raise RuntimeError('Cannot use initialize EL twice') logger.info('EyeLink: Initializing on {}'.format(link)) ec.flush() if link is not None: iswin = (sys.platform == 'win32') cmd = 'ping -n 1 -w 100' if iswin else 'fping -c 1 -t100' cmd = subprocess.Popen('%s %s' % (cmd, link), stdout=subprocess.PIPE, stderr=subprocess.PIPE) if cmd.returncode: raise RuntimeError('could not connect to Eyelink @ %s, ' 'is it turned on?' % link) self._eyelink = DummyEl() if link is None else pylink.EyeLink(link) self._file_list = [] self._size = np.array(self._ec.window_size_pix) self._ec._extra_cleanup_fun += [self._close] self._ec.flush() self._setup(fs) self._ec._id_call_dict['el_id'] = self._stamp_trial_id self._ec._ofp_critical_funs.append(self._stamp_trial_start) self._ec._on_trial_ok.append(self._stamp_trial_ok) self._fake_calibration = False # Only used for testing self._closed = False # to prevent double-closing self._current_open_file = None logger.debug('EyeLink: Setup complete') self._ec.flush()
def runExperiment(self): ''' Connect to the eye tracker and do calibration''' try: self.eyeTracker = pylink.EyeLink('100.1.1.1') self.eyeTracker.doTrackerSetup() except: print "Could not connect to eye tracker" ''' Start recording thread ''' self.captureFlag = True recordingThread = threading.Thread(target=self.recordingThread) recordingThread.start() ''' Run experiments ''' self.runAntisaccades() ''' Cleanup ''' self.captureFlag = False if not self.eyeTracker is None: self.eyeTracker.close() self.eyeTracker = None
def eyeTrkInit (dr): el = pl.EyeLink() # sending the screen dimensions to the eye tracker: el.sendCommand('screen_pixel_coords = 0 0 %d %d' %dr) el.sendMessage('DISPLAY_COORDS 0 0 %d %d' %dr) el.sendCommand('generate_default_targets = NO') el.sendCommand('calibration_targets = %d,%d %d,%d %d,%d' % ( calTarg1[0], calTarg1[1], calTarg2[0], calTarg2[1], calTarg3[0], calTarg3[1]) ) el.sendCommand('validation_targets = %d,%d %d,%d %d,%d' % ( calTarg1[0], calTarg1[1], calTarg2[0], calTarg2[1], calTarg3[0], calTarg3[1]) ) # parser configuration 1 corresponds to high sensitivity to saccades: el.sendCommand('select_parser_configuration 1') # turns off "scenelink camera stuff", i.e., doesn't record the ET video el.sendCommand('scene_camera_gazemap = NO') # converting pupil area to diameter el.sendCommand('pupil_size_diameter = %s'%('YES')) return(el)
def eyelink(): print 'TESTING EYELINK' subject_id = 'TEST' window = visual.Window([1920, 1080], fullscr=1, monitor="testMonitor", units="pix", color=[1, 1, 1]) window.mouseVisible = False # connect to eye tracker tracker = pylink.EyeLink('100.1.1.1') link = tracker_functions.eyelink(tracker, subject_id) link.eye_tracker_setup() # Open an EDF file to store gaze data -- name cannot exceeds 8 characters tracker.openDataFile(link.data_file_name) tracker.sendCommand("testing the combination of video with eye tracker") # set up monitors between eyelink and this computer window, movie, frame_time = link.movie_setup(window) # connect to biopac biopac = experiment_ports.biopac() # initiate biopack. set all to 0 except for "not experiment" channel biopac.initiate() # begin experiment: recording physio data and presenting video biopac.begin() # calibrate subjects link.calibration(tracker, window) print 'EYELINK COMPLETED SUCCESSFULLY'
def __init__(self, win, clock, sj="TEST", saccadeSensitivity=HIGH, calibrationType='HV9', calibrationTargetColor=WHITE, calibrationBgColor=BLACK, CalibrationSounds=False, screen=(1024, 768)): '''win: psychopy visual window used for the experiment clock: psychopy time clock recording time for whole experiment sj: Subject identifier string (affects EDF filename) saccadeSensitivity: HIGH: Pursuit and neurological work LOW: Cognitive research calibrationType: H3: Horizontal 3-point HV3: 3-point calibration, poor linearization HV5: 5-point calibration, poor at corners HV9: 9-point calibration, best overall calibrationTargetColor and calibrationBgColor: RGB tuple, i.e., (255,0,0) for Red One of: BLACK, WHITE, GRAY calibrationSounds: True: enable feedback sounds when calibrating''' self.edfFileName = str( sj) + ".EDF" # Subject name only can put 8 characters print("Connecting to eyetracker.") self.tracker = pylink.EyeLink() self.timeCorrection = clock.getTime() - self.tracker.trackerTime() print("Loading custom graphics") #Initializes Experiment Graphics genv = EyeLinkCoreGraphicsPsychopy(self.tracker, win, screen) pylink.openGraphicsEx(genv) # opendatafile self.tracker.openDataFile(self.edfFileName) #EyeLink Tracker Configuration pylink.flushGetkeyQueue() # Initializes the key queue used by getkey(). It may be called at any time to get rid any of old keys from the queue. self.tracker.setOfflineMode() #Places EyeLink tracker in off-line (idle) mode. Wait till the tracker has finished the mode transition self.tracker.sendCommand("screen_pixel_coords = 0 0 %d %d" % (tuple(screen))) self.tracker.setCalibrationType(calibrationType) self.tracker.sendCommand( "driftcorrect_cr_disable=OFF" ) #CF - OFF: turns on drift CORRECT; AUTO: Turns on drift CHECK; ON: Turns off both #self.tracker.sendCommand("generate_default_targets = NO") #self.tracker.sendCommand("calibration_targets = 512,384 512,417 512,351 402,384 622,384 402,417 622,417 402,351 622,351") #self.tracker.sendCommand("validation_targets = 512,384 512,417 512,351 402,384 622,384 402,417 622,417 402,351 622,351") self.tracker.sendMessage("DISPLAY_COORDS 0 0 %d %d" % (tuple(screen))) eyelink_ver = self.tracker.getTrackerVersion() if eyelink_ver == 3: tvstr = self.tracker.getTrackerVersionString() vindex = tvstr.find("EYELINK CL") tracker_software_ver = int( float(tvstr[(vindex + len("EYELINK CL")):].strip())) else: tracker_software_ver = 0 if eyelink_ver >= 2: self.tracker.sendCommand("select_parser_configuration %d" % saccadeSensitivity) else: if saccadeSensitivity == HIGH: svt, sat = 22, 5000 else: svt, sat = 30, 9500 self.tracker.sendCommand("saccade_velocity_threshold = %d" % svt) self.tracker.sendCommand("saccade_acceleration_threshold = %d" % sat) if eyelink_ver == 2: #turn off scenelink camera stuff self.tracker.sendCommand("scene_camera_gazemap = NO") # set EDF file contents self.tracker.setFileEventFilter( "LEFT,RIGHT,FIXATION,SACCADE,BLINK,MESSAGE,BUTTON") if tracker_software_ver >= 4: self.tracker.setFileSampleFilter( "LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS,HTARGET") else: self.tracker.setFileSampleFilter( "LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS") # set link data (used for gaze cursor) self.tracker.setLinkEventFilter( "LEFT,RIGHT,FIXATION,SACCADE,BLINK,BUTTON") if tracker_software_ver >= 4: self.tracker.setLinkSampleFilter( "LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS,HTARGET") else: self.tracker.setLinkSampleFilter( "LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS") #self.tracker.setAcceptTargetFixationButton(1) # This programs a specific button for use in drift correction. #Set the calibration settings: #pylink.setCalibrationColors(WHITE, BLACK) # Sets the calibration target and background color(foreground_color, background_color) if CalibrationSounds: pylink.setCalibrationSounds("", "", "") pylink.setDriftCorrectSounds("", "off", "off") else: pylink.setCalibrationSounds("off", "off", "off") pylink.setDriftCorrectSounds("off", "off", "off") print("Beginning tracker setup") self.tracker.doTrackerSetup()
def __init__(self, display, resolution=settings.DISPSIZE, data_file=settings.LOGFILENAME + ".edf", fg_color=settings.FGC, bg_color=settings.BGC, eventdetection=settings.EVENTDETECTION, saccade_velocity_threshold=35, saccade_acceleration_threshold=9500, blink_threshold=settings.BLINKTHRESH, force_drift_correct=True, pupil_size_mode=settings.EYELINKPUPILSIZEMODE, **args): """See pygaze._eyetracker.baseeyetracker.BaseEyeTracker""" # try to import copy docstring (but ignore it if it fails, as we do # not need it for actual functioning of the code) try: copy_docstr(BaseEyeTracker, libeyelink) except: # we're not even going to show a warning, since the copied # docstring is useful for code editors; these load the docs # in a non-verbose manner, so warning messages would be lost pass global _eyelink # Make sure that we have a valid data file. The local_data_file may # contain a folder. The eyelink_data_file is only a basename, i.e. # without folder. The eyelink_data_file must be at most eight characters # and end with a `.edf` extension. self.local_data_file = data_file self.eyelink_data_file = os.path.basename(data_file) stem, ext = os.path.splitext(self.eyelink_data_file) if len(stem) > 8 or ext.lower() != '.edf': raise Exception( "The EyeLink cannot handle filenames longer than eight " "characters (excluding '.edf' extension).") # properties self.display = display self.fontsize = 18 self.scr = Screen(disptype=settings.DISPTYPE, mousevisible=False) self.kb = Keyboard(keylist=["escape", "q"], timeout=1) self.resolution = resolution self.recording = False self.saccade_velocity_treshold = saccade_velocity_threshold self.saccade_acceleration_treshold = saccade_acceleration_threshold self.blink_threshold = blink_threshold self.eye_used = None self.left_eye = 0 self.right_eye = 1 self.binocular = 2 self.pupil_size_mode = pupil_size_mode self.prevsample = (-1, -1) self.prevps = -1 # event detection properties # degrees; maximal distance from fixation start (if gaze wanders beyond # this, fixation has stopped) self.fixtresh = 1.5 # milliseconds; amount of time gaze has to linger within self.fixtresh # to be marked as a fixation self.fixtimetresh = 100 # degrees per second; saccade velocity threshold self.spdtresh = self.saccade_velocity_treshold # degrees per second**2; saccade acceleration threshold self.accthresh = self.saccade_acceleration_treshold self.set_detection_type(eventdetection) # weighted distance, used for determining whether a movement is due to # measurement error (1 is ok, higher is more conservative and will # result in only larger saccades to be detected) self.weightdist = 10 # distance between participant and screen in cm self.screendist = settings.SCREENDIST # distance between participant and screen in cm self.screensize = settings.SCREENSIZE self.pixpercm = (self.resolution[0]/float(self.screensize[0]) + \ self.resolution[1]/float(self.screensize[1])) / 2.0 # only initialize eyelink once if _eyelink == None: try: _eyelink = pylink.EyeLink() except: raise Exception( "Error in libeyelink.libeyelink.__init__(): Failed to " "connect to the tracker!") # determine software version of tracker self.tracker_software_ver = 0 self.eyelink_ver = pylink.getEYELINK().getTrackerVersion() if self.eyelink_ver == 3: tvstr = pylink.getEYELINK().getTrackerVersionString() vindex = tvstr.find("EYELINK CL") self.tracker_software_ver = int(float(tvstr[(vindex + \ len("EYELINK CL")):].strip())) if self.eyelink_ver == 1: self.eyelink_model = 'EyeLink I' elif self.eyelink_ver == 2: self.eyelink_model = 'EyeLink II' elif self.eyelink_ver == 3: self.eyelink_model = 'EyeLink 1000' else: self.eyelink_model = 'EyeLink (model unknown)' # Open graphics self.eyelink_graphics = EyelinkGraphics(self, _eyelink) pylink.openGraphicsEx(self.eyelink_graphics) # Optionally force drift correction. For some reason this must be done # as (one of) the first things, otherwise a segmentation fault occurs. if force_drift_correct: try: self.send_command('driftcorrect_cr_disable = OFF') except: print('Failed to force drift correction (EyeLink 1000 only)') # Set pupil-size mode if self.pupil_size_mode == 'area': pylink.getEYELINK().setPupilSizeDiameter(False) elif self.pupil_size_mode == 'diameter': pylink.getEYELINK().setPupilSizeDiameter(True) else: raise Exception( "pupil_size_mode should be 'area' or 'diameter', not %s" \ % self.pupil_size_mode) pylink.getEYELINK().openDataFile(self.eyelink_data_file) pylink.flushGetkeyQueue() pylink.getEYELINK().setOfflineMode() # notify eyelink of display resolution self.send_command("screen_pixel_coords = 0 0 %d %d" % \ (self.resolution[0], self.resolution[1])) # get some configuration stuff if self.eyelink_ver >= 2: self.send_command("select_parser_configuration 0") if self.eyelink_ver == 2: # turn off scenelink camera stuff self.send_command("scene_camera_gazemap = NO") # set EDF file contents (this specifies which data is written to the EDF # file) self.send_command( "file_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,MESSAGE,BUTTON" ) if self.tracker_software_ver >= 4: self.send_command( "file_sample_data = LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS,HTARGET" ) else: self.send_command( "file_sample_data = LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS") # set link data (this specifies which data is sent through the link and # thus can be used in gaze contingent displays) self.send_command( "link_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,BUTTON") if self.tracker_software_ver >= 4: self.send_command( "link_sample_data = LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS,HTARGET" ) else: self.send_command( "link_sample_data = LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS") # not quite sure what this means (according to Sebastiaan Mathot, it # might be the button that is used to end drift correction?) self.send_command("button_function 5 'accept_target_fixation'") if not self.connected(): raise Exception( "Error in libeyelink.libeyelink.__init__(): Failed to connect " "to the eyetracker!")
from psychopy import visual, monitors, gui, core import pylink import serial, serial.tools.list_ports import time from general.config_hardware import scnWIDTH, scnHEIGHT import os from EyeLinkCoreGraphicsPsychoPy import EyeLinkCoreGraphicsPsychoPy import pylink import general.variables as variables tk = pylink.EyeLink('100.1.1.1') edfDataFolder = (os.getcwd() + "\\data_recorded\\edfData") expInfo = { 'Subject': '159', 'Sex': 'Female', 'Age': 20, 'Dominant_eye': 'right', 'Dominant_hand': 'right' } WIN = visual.Window( (1200, 900), monitor='testMonitor', units='deg', allowStencil=True, color=[-1, -1, -1] ) # Just for TESTING. In the final experiment the line below should be activate def initTk(expInfo): ## Data host ## if not os.path.exists(edfDataFolder):
# Filename: interest_area.py import pylink # connect to the tracker tk = pylink.EyeLink() # open an EDF on the Host tk.openDataFile('seg.edf') # run through five trials for trial in range(1, 6): #print a message to show the current trial # print("Trial #: %d" % trial) # log a TRIALID message to mark trial start tk.sendMessage('TRIALID %d' % trial) tk.startRecording(1, 1, 1, 1) # start recording # interest area definitions tk.sendMessage('!V IAREA ELLIPSE 1 0 0 100 100 head') tk.sendMessage('!V IAREA RECTANGLE 2 85 85 285 185 body') tk.sendMessage('!V IAREA FREEHAND 3 285,125 385,50 335,125 tail') pylink.pumpDelay(2000) # record for 2-sec tk.stopRecording() # stop recording # store trial variables in the EDF data file tk.sendMessage('!V TRIAL_VAR condition step') tk.sendMessage('!V TRIAL_VAR gap_duration 200') tk.sendMessage('!V TRIAL_VAR direction Right')
def __init__(self, resolution, data_file="default.edf", fg_color=(255, 255, 255), bg_color=(0, 0, 0), saccade_velocity_threshold=35, saccade_acceleration_threshold=9500): """ Initializes the connection to the Eyelink Parameters: _resolution: (width, height) tuple _data_file: the name of the EDF file Returns: True on connection success and False on connection failure """ global _eyelink self.data_file = data_file self.resolution = resolution self.recording = False self.saccade_velocity_treshold = saccade_velocity_threshold self.saccade_acceleration_treshold = saccade_acceleration_threshold self.eye_used = None self.left_eye = 0 self.right_eye = 1 self.binocular = 2 # Only initialize the eyelink once if _eyelink == None: try: _eyelink = pylink.EyeLink() except Exception as e: raise exceptions.runtime_error( "Failed to connect to the tracker: %s" % e) graphics_env = eyelink_graphics(_eyelink) pylink.openGraphicsEx(graphics_env) pylink.getEYELINK().openDataFile(self.data_file) pylink.flushGetkeyQueue() pylink.getEYELINK().setOfflineMode() # Notify the eyelink of the display resolution self.send_command("screen_pixel_coords = 0 0 %d %d" % (self.resolution[0], self.resolution[1])) # Determine the software version of the tracker self.tracker_software_ver = 0 self.eyelink_ver = pylink.getEYELINK().getTrackerVersion() if self.eyelink_ver == 3: tvstr = pylink.getEYELINK().getTrackerVersionString() vindex = tvstr.find("EYELINK CL") self.tracker_software_ver = int( float(tvstr[(vindex + len("EYELINK CL")):].strip())) # Set some configuration stuff (not sure what the parser and gazemap mean) if self.eyelink_ver >= 2: self.send_command("select_parser_configuration 0") if self.eyelink_ver == 2: #turn off scenelink camera stuff self.send_command("scene_camera_gazemap = NO") else: self.send_command("saccade_velocity_threshold = %d" % self.saccade_velocity_threshold) self.send_command("saccade_acceleration_threshold = %s" % self.saccade_acceleration_threshold) # Set EDF file contents. This specifies which data is written to the EDF file. self.send_command( "file_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,MESSAGE,BUTTON" ) if self.tracker_software_ver >= 4: self.send_command( "file_sample_data = LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS,HTARGET" ) else: self.send_command( "file_sample_data = LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS") # Set link data. This specifies which data is sent through the link and thus can # be used in gaze contingent displays self.send_command( "link_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,BUTTON") if self.tracker_software_ver >= 4: self.send_command( "link_sample_data = LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS,HTARGET" ) else: self.send_command( "link_sample_data = LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS") # Not sure what this means. Maybe the button that is used to end drift correction? self.send_command("button_function 5 'accept_target_fixation'") if not self.connected(): raise exceptions.runtime_error( "Failed to connect to the eyetracker")
def run(self_report, window): """Present video, collect SCR and gaze data, align with video.""" # connect to eye tracker tracker = pylink.EyeLink('100.1.1.1') link = tracker_functions.eyelink(tracker, self_report['subject_id']) link.eye_tracker_setup() # Open an EDF file to store gaze data -- name cannot exceeds 8 characters tracker.openDataFile(link.data_file_name) tracker.sendCommand("day two of data collection") # set up monitors between eyelink and this computer window = link.display_setup(window) # wait for a given interval so subjects physiological respones "settle" core.wait(wait_time) # calibrate subjects, determine whether we're using their gaze data link.calibration(tracker, window, day=self_report['day']) # connect to biopac biopac = experiment_ports.biopac() # initiate biopack. set all to 0 except for "not experiment" channel biopac.initiate() # begin experiment: recording physio data and presenting video biopac.begin() # load stimulus parameters cs, cs_type, colors, inter_trial_interval = params.stimulus_parameters(self_report) # wait to begin experiment, after instructions have ended core.wait(delay_time) # start recording eyegaze link.initiate(tracker) # one last "Press any button to continue" # begin stimulus presentation for i_stimulus in range(len(cs)): # select and present next stimulus color i_color = colors[cs[i_stimulus]] present_stimulus(i_color, window, visual) # send CS info to biopac and eyetracker start_message = 'START_CS%s'%cs_type[cs[i_stimulus]] tracker.sendMessage(start_message) biopac.CS(cs[i_stimulus]) # wait for stimulus presentation core.wait(n_second_display) # signal end to biopac and eyetracker end_message = 'END_CS%s'%cs_type[cs[i_stimulus]] tracker.sendMessage(end_message) biopac.end_stim() # clear screen and wait the duration of the iti window.flip(); core.wait(inter_trial_interval[i_stimulus]) # end video, transfer eye_tracker data, close tracker and biopac link.close(tracker) biopac.end() self_report['CS'] = cs self_report['isi'] = inter_trial_interval return self_report, window
]) eye = None # left ("left") or right ("right") eye used for EyeLink. Used for gaze contingent display last_ET = 0 # last gaze position # Getting the radius of the space of the central fixation point TRACKER_FX_RADIUS = 900 TRACKER_FX_RADIUS_screen = 1600 RESOLUTION = [1280, 900] # [1280,720][1600,900]# tracker = True # Set a few task parameters useGUI = True # whether use the Psychopy GUI module to collect subject information dummyMode = not tracker # If in Dummy Mode, press ESCAPE to skip calibration/validataion #### EYELINK LINK: established a link to the tracker ############################################### if not dummyMode: tk = pylink.EyeLink('100.1.1.1') else: tk = pylink.EyeLink(None) #### EYELINK FILE: Open an EDF data file EARLY #################################################### # Eye to be tracked eye = "left" # Note that for Eyelink 1000/II, the file name cannot exceeds 8 characters # we need to open eyelink data files early so as to record as much info as possible tk.openDataFile(EDF) # add personalized header (preamble text) tk.sendCommand("add_file_preamble_text 'Psychopy GC demo'") screen, screen_width, screen_height = psypsyinterface.initialisation_pygame( (200, 200, 200))
def doSim(self, trial, road, duration, tau, doEyetrack): # Measure sample rate in order to calculate delay buffer sample_rate = self.screen.measure_refresh_rate(2.0) print "Sample rate: " + str(sample_rate) #sample_rate = 60 self.doEyetrack = doEyetrack self.pos_ring = RingBuffer(self.center, int(math.floor(tau * sample_rate)) + 1) print("Ring Buffer:: size: " + str(self.pos_ring.size)) if doEyetrack: import pylink from EyeLinkCoreGraphicsVE import EyeLinkCoreGraphicsVE self.tracker = pylink.EyeLink() if self.tracker == None: print "Error: Eyelink is not connected" sys.exit() genv = EyeLinkCoreGraphicsVE(self.screen, self.tracker) pylink.openGraphicsEx(genv) #Opens the EDF file. edfFileName = "TRIAL" + str(trial) + ".EDF" self.tracker.openDataFile(edfFileName) pylink.flushGetkeyQueue() self.tracker.sendCommand("screen_pixel_coords = 0 0 %d %d" % (VisionEgg.config.VISIONEGG_SCREEN_W, VisionEgg.config.VISIONEGG_SCREEN_H)) tracker_software_ver = 0 eyelink_ver = self.tracker.getTrackerVersion() if eyelink_ver == 3: tvstr = self.tracker.getTrackerVersionString() vindex = tvstr.find("EYELINK CL") tracker_software_ver = int( float(tvstr[(vindex + len("EYELINK CL")):].strip())) if eyelink_ver >= 2: self.tracker.sendCommand("select_parser_configuration 0") if eyelink_ver == 2: #turn off scenelink camera stuff self.tracker.sendCommand("scene_camera_gazemap = NO") else: self.tracker.sendCommand("saccade_velocity_threshold = 35") self.tracker.sendCommand( "saccade_acceleration_threshold = 9500") # set EDF file contents self.tracker.sendCommand( "file_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,MESSAGE,BUTTON" ) if tracker_software_ver >= 4: self.tracker.sendCommand( "file_sample_data = LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS,HTARGET" ) else: self.tracker.sendCommand( "file_sample_data = LEFT,RIGHT,GAZE,AREA,GAZERES,STATUS") # set link data (used for gaze cursor) self.tracker.sendCommand( "link_event_filter = LEFT,RIGHT,FIXATION,SACCADE,BLINK,BUTTON") if tracker_software_ver >= 4: self.tracker.sendCommand( "link_sample_data = LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS,HTARGET" ) else: self.tracker.sendCommand( "link_sample_data = LEFT,RIGHT,GAZE,GAZERES,AREA,STATUS") if not self.doneSetup: self.tracker.doTrackerSetup() self.doneSetup = True else: while 1: try: error = self.tracker.doDriftCorrect( self.screen.size[0] / 2, self.screen.size[1] / 2, 1, 1) if error != 27: # ?? from example break else: self.tracker.doTrackerSetup() except: break self.screen.parameters.bgcolor = 106.0 / 255.0, 147.0 / 255.0, 0.0 # Load road data from file and create an image roadArray = numpy.loadtxt('road' + str(road) + '.txt') # Convert to a Path roadPath = ImagePath.Path( map(lambda xy: (xy[0], xy[1]), roadArray.tolist())) # Use Path to create a plot of the road im = Image.new("RGB", (2000, 100), (50, 50, 50)) draw = ImageDraw.Draw(im) # draw each side of the road separately draw.line(roadPath[:4000], fill=(200, 200, 200)) draw.line(roadPath[4000:], fill=(200, 200, 200)) del draw # Lay out a road texture in the x-z plane roadTexture = Texture(im) del im eye_height = 2.5 vertices = [(-10, -eye_height, 0), (-10, -eye_height, -1000), (10, -eye_height, 0), (10, -eye_height, -1000)] rect = TextureStimulus3D(texture=roadTexture, lowerleft=vertices[0], lowerright=vertices[1], upperleft=vertices[2], upperright=vertices[3]) # We will use these later for our camera transforms self.camera_matrix = ModelView() self.frame_timer = FrameTimer() self.outf = open( 'steersim-' + str(trial) + '-' + str(road) + '-out.txt', 'wb') # Vewport for the road viewport3D = Viewport( screen=self.screen, projection=SimplePerspectiveProjection(fov_x=75.2), camera_matrix=self.camera_matrix, stimuli=[rect]) # Construct a sky sky_l = 0 sky_r = self.screen.size[0] sky_t = self.screen.size[1] sky_b = self.screen.size[1] / 2 sky_vertices = [(sky_l, sky_t, 0), (sky_r, sky_t, 0), (sky_r, sky_b, 0), (sky_l, sky_b, 0)] sky = Rectangle3D(color=(144.0 / 255.0, 190.0 / 255.0, 1.0), vertex1=sky_vertices[0], vertex2=sky_vertices[1], vertex3=sky_vertices[2], vertex4=sky_vertices[3]) wheelTexture = Texture('wheel.png') self.wheel = TextureStimulus(texture=wheelTexture, internal_format=gl.GL_RGBA, position=(self.center, -75), anchor='center') # display the sky in its own viewport viewport2D = Viewport(screen=self.screen) viewport2D.parameters.stimuli = [sky, self.wheel] self.init_state() askText = Text(text='Press a key to start', anchor='center', position=(self.center, self.screen.size[1] / 2)) splash = Viewport(screen=self.screen) splash.parameters.stimuli = [askText] self.askForNext = Presentation(go_duration=(0.5, 'seconds'), viewports=[splash]) self.askForNext.add_controller( None, None, FunctionController(during_go_func=self.wait_for_key)) self.askForNext.parameters.enter_go_loop = True self.askForNext.run_forever() self.simPres = Presentation(go_duration=(duration, 'seconds'), viewports=[viewport3D, viewport2D], handle_event_callbacks=[ (pygame.KEYDOWN, self.check_keypress) ]) self.simPres.add_controller( None, None, FunctionController(during_go_func=self.update)) if doEyetrack: startTime = pylink.currentTime() self.tracker.sendMessage("SYNCTIME %d" % (pylink.currentTime() - startTime)) error = self.tracker.startRecording(1, 1, 1, 1) self.tracker.sendMessage("PRES %d START" % (trial)) self.simPres.go() if doEyetrack: self.tracker.sendMessage("PRES %d END" % (trial)) self.tracker.stopRecording() # File transfer and cleanup! self.tracker.setOfflineMode() pylink.msecDelay(500) #Close the file and transfer it to Display PC self.tracker.closeDataFile() self.tracker.receiveDataFile(edfFileName, edfFileName) self.outf.close() if self.quit: raise SystemExit
import numpy as np from psychopy import core, visual, event, logging import random import pylink import pygame import socket server = socket.socket() tracker_connected = False tracker_ip = "100.1.1.1" edf_filename = "trial_eyetracker_output.edf" window_size = (800, 600) if tracker_connected: eye_tracker = pylink.EyeLink(tracker_ip) elif not tracker_connected: eye_tracker = pylink.EyeLink(None) # #open output file pylink.getEYELINK().openDataFile('test_output') win = visual.Window(size=window_size) #send screen size to tracker pylink.getEYELINK().sendCommand("screen_pixel_coords = 0 0 %d %d" % (window_size[0], window_size[1])) pylink.getEYELINK().sendMessage("screen_pixel_coords = 0 0 %d %d" % (window_size[0], window_size[1]))
def EyelinkStart(dispsize, Name, win, bits=32, dummy=False, colors=((0, 0, 0), (192, 192, 192))): """ Performs startup routines for the EyeLink 1000 Plus eyetracker. **Author** : Wanja Mössing, WWU Münster | [email protected] \n *July 2017* Parameters: ----------- dispsize : tuple two-item tuple width & height in px Name : string filename for the edf. Doesn't have to, but can, end on '.edf' Maximum length is 8 (without '.edf'). Possible alphanumeric input: 'a-z', 'A-Z', '0-9', '-' & '_' win : window object You necessarily need to open a psychopy window first! bits : integer color-depth, defaults to 32 dummy : boolean Run tracker in dummy mode? colors : Tuple, Optional. Tuple with two RGB triplets Returns ------- 'el' the tracker object. This can be passed to other functions, although they can use pylink.getEYELINK() to find it automatically. """ print('. ') # get filename if '.edf' not in Name.lower(): if len(Name) > 8: print('EDF filename too long! (1-8 characters/letters)') raise SystemExit else: Name += '.edf' elif '.edf' in Name.lower(): if len(Name) > 12: print('EDF filename too long! (1-8 characters/letters)') raise SystemExit print('. ') # initialize tracker object if dummy: el = pylink.EyeLink(None) else: el = pylink.EyeLink("100.1.1.1") print('. ') # Open EDF file on host el.openDataFile(Name) print('. ') # set file preamble currentdir = path.basename(getcwd()) FilePreamble = "add_file_preamble_text \'" FilePreamble += "Eyetracking Dataset AE Busch WWU Muenster Experiment: " FilePreamble += currentdir + "\'" el.sendCommand(FilePreamble) print('. ') # this function calls the custom calibration routine # "EyeLinkCoreGraphicsPsychopy.py" genv = EyeLinkCoreGraphicsPsychoPy(el, win) pylink.openGraphicsEx(genv) print('. ') # set tracker offline to change configuration el.setOfflineMode() print('. ') # flush old keys pylink.flushGetkeyQueue() print('. ') # set sampling rate el.sendCommand('sample_rate 1000') print('. ') # Sets the display coordinate system and sends mesage to that # effect to EDF file; el.sendCommand("screen_pixel_coords = 0 0 %d %d" % (dispsize[0] - 1, dispsize[1] - 1)) el.sendMessage("DISPLAY_COORDS 0 0 %d %d" % (dispsize[0] - 1, dispsize[1] - 1)) print('. ') # select parser configuration for online saccade etc detection ELversion = el.getTrackerVersion() ELsoftVer = 0 if ELversion == 3: tmp = el.getTrackerVersionString() tmpidx = tmp.find('EYELINK CL') ELsoftVer = int(float(tmp[(tmpidx + len("EYELINK CL")):].strip())) if ELversion >= 2: el.sendCommand("select_parser_configuration 0") if ELversion == 2: # turn off scenelink stuff (that's an EL2 front-cam addon...) el.sendCommand("scene_camera_gazemap = NO") else: el.sendCommand("saccade_velocity_threshold = 35") el.sendCommand("saccade_acceleration_threshold = 9500") print('. ') # set EDF file contents AREA el.sendCommand("file_event_filter = LEFT,RIGHT,FIXATION," "SACCADE,BLINK,MESSAGE,BUTTON,INPUT") if ELsoftVer >= 4: el.sendCommand("file_sample_data = LEFT,RIGHT,GAZE,HREF," "AREA,HTARGET,GAZERES,STATUS,INPUT") else: el.sendCommand("file_sample_data = LEFT,RIGHT,GAZE,HREF," "AREA,GAZERES,STATUS,INPUT") print('. ') # set link data (online interaction)AREA el.sendCommand("link_event_filter = LEFT,RIGHT,FIXATION,SACCADE," "BLINK,MESSAGE,BUTTON,INPUT") if ELsoftVer >= 4: el.sendCommand("link_sample_data = LEFT,RIGHT,GAZE,GAZERES,AREA," "HTARGET,STATUS,INPUT") else: el.sendCommand("link_sample_data = LEFT,RIGHT,GAZE,GAZERES,AREA," "STATUS,INPUT") print('. ') # run initial calibration # 13-Pt Grid calibration el.sendCommand('calibration_type = HV13') EyelinkCalibrate(dispsize, el) print('. ') # put tracker in idle mode and wait 50ms, then really start it. el.sendMessage('SETUP_FINISHED') el.setOfflineMode() pylink.msecDelay(500) print('. ') # set to realtime mode pylink.beginRealTimeMode(200) # start recording # note: sending everything over the link *potentially* causes buffer # overflow. However, with modern PCs and EL1000+ this shouldn't be a real # problem el.startRecording(1, 1, 1, 1) # to activate parallel port readout without modifying the FINAL.INI on the # eyelink host pc, uncomment these lines # tyical settings for straight-through TTL cable (data pins -> data pins) el.sendCommand('write_ioport 0xA 0x20') el.sendCommand('create_button 1 8 0x01 0') el.sendCommand('create_button 2 8 0x02 0') el.sendCommand('create_button 3 8 0x04 0') el.sendCommand('create_button 4 8 0x08 0') el.sendCommand('create_button 5 8 0x10 0') el.sendCommand('create_button 6 8 0x20 0') el.sendCommand('create_button 7 8 0x40 0') el.sendCommand('create_button 8 8 0x80 0') el.sendCommand('input_data_ports = 8') el.sendCommand('input_data_masks = 0xFF') # tyical settings for crossover TTL cable (data pins -> status pins) # el.sendCommand('write_ioport 0xA 0x0') # el.sendCommand('create_button 1 9 0x20 1') # el.sendCommand('create_button 2 9 0x40 1') # el.sendCommand('create_button 3 9 0x08 1') # el.sendCommand('create_button 4 9 0x10 1') # el.sendCommand('create_button 5 9 0x80 0') # el.sendCommand('input_data_ports = 9') # el.sendCommand('input_data_masks = 0xFF') # mark end of Eyelinkstart in .edf el.sendMessage('>EndOfEyeLinkStart') # return Eyelink object return el