def __init__(self, display): """Initiates an eyetracker dummy object, that simulates gaze position using the mouse arguments display -- a pygaze display.Display instance keyword arguments None """ # try to copy docstrings (but ignore it if it fails, as we do # not need it for actual functioning of the code) try: copy_docstr(BaseEyeTracker, Dummy) 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 self.recording = False self.blinking = False self.bbpos = (settings.DISPSIZE[0]/2, settings.DISPSIZE[1]/2) self.resolution = settings.DISPSIZE[:] self.simulator = Mouse(disptype=settings.DISPTYPE, mousebuttonlist=None, timeout=2, visible=False) self.kb = Keyboard(disptype=settings.DISPTYPE, keylist=None, timeout=None) self.angrybeep = Sound(osc='saw',freq=100, length=100, attack=0, decay=0, soundfile=None) self.display = display self.screen = Screen(disptype=settings.DISPTYPE, mousevisible=False)
def __init__(self, display, logfile=settings.LOGFILE, \ alea_key=settings.ALEAKEY, \ animated_calibration=settings.ALEAANIMATEDCALIBRATION, \ eventdetection=settings.EVENTDETECTION, \ saccade_velocity_threshold=35, \ saccade_acceleration_threshold=9500, \ blink_threshold=settings.BLINKTHRESH, \ **args): """Initializes the AleaTracker object arguments display -- a pygaze.display.Display instance keyword arguments logfile -- logfile name (string value); note that this is the name for the eye data log file (default = LOGFILE) """ # try to copy docstrings (but ignore it if it fails, as we do # not need it for actual functioning of the code) try: copy_docstr(BaseEyeTracker, AleaTracker) 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 # object properties self.disp = display self.screen = Screen() self.dispsize = self.disp.dispsize # display size in pixels self.screensize = settings.SCREENSIZE # display size in cm self.kb = Keyboard(keylist=['space', 'escape', 'q'], timeout=1) self.errorbeep = Sound(osc='saw', freq=100, length=100) # show a message self.screen.clear() self.screen.draw_text( text="Initialising the eye tracker, please wait...", fontsize=20) self.disp.fill(self.screen) self.disp.show() # output file properties self.outputfile = logfile + '.tsv' # calibration properties self.animated_calibration = animated_calibration == True # eye tracker properties self.connected = False self.recording = False self.errdist = 2 # degrees; maximal error for drift correction self.pxerrdist = 30 # initial error in pixels self.maxtries = 100 # number of samples obtained before giving up (for obtaining accuracy and tracker distance information, as well as starting or stopping recording) self.prevsample = (-1, -1) self.prevps = -1 # event detection properties self.fixtresh = 1.5 # degrees; maximal distance from fixation start (if gaze wanders beyond this, fixation has stopped) self.fixtimetresh = 100 # milliseconds; amount of time gaze has to linger within self.fixtresh to be marked as a fixation self.spdtresh = saccade_velocity_threshold # degrees per second; saccade velocity threshold self.accthresh = saccade_acceleration_threshold # degrees per second**2; saccade acceleration threshold self.blinkthresh = blink_threshold # milliseconds; blink detection threshold used in PyGaze method self.eventdetection = eventdetection self.set_detection_type(self.eventdetection) self.weightdist = 10 # 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) # connect to the tracker self.alea = OGAleaTracker(alea_key, file_path=self.outputfile) # get info on the sample rate # TODO: Compute after streaming some samples? self.samplerate = 60.0 self.sampletime = 1000.0 / self.samplerate # initiation report self.log("pygaze initiation report start") self.log("display resolution: {}x{}".format( \ self.dispsize[0], self.dispsize[1])) self.log("display size in cm: {}x{}".format( \ self.screensize[0], self.screensize[1])) self.log("samplerate: {} Hz".format(self.samplerate)) self.log("sampletime: {} ms".format(self.sampletime)) self.log("fixation threshold: {} degrees".format(self.fixtresh)) self.log("speed threshold: {} degrees/second".format(self.spdtresh)) self.log("acceleration threshold: {} degrees/second**2".format( \ self.accthresh)) self.log("pygaze initiation report end")
def __init__(self, display, ip='127.0.0.1', sendport=4444, receiveport=5555, logfile=settings.LOGFILE, eventdetection=settings.EVENTDETECTION, saccade_velocity_threshold=35, saccade_acceleration_threshold=9500, **args): """Initializes the SMItracker object arguments display -- a pygaze.display.Display instance keyword arguments ip -- internal ip address for iViewX (default = '127.0.0.1') sendport -- port number for iViewX sending (default = 4444) receiveport -- port number for iViewX receiving (default = 5555) logfile -- logfile name (string value); note that this is the name for the SMI logfile, NOT the .idf file (default = LOGFILE) """ # try to copy docstrings (but ignore it if it fails, as we do # not need it for actual functioning of the code) try: copy_docstr(BaseEyeTracker, SMITracker) 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 # object properties self.disp = display self.screen = Screen() self.dispsize = settings.DISPSIZE # display size in pixels self.screensize = settings.SCREENSIZE # display size in cm self.kb = Keyboard(keylist=['space', 'escape', 'q'], timeout=1) self.errorbeep = Sound(osc='saw', freq=100, length=100) # output file properties self.outputfile = logfile self.description = "experiment" # TODO: EXPERIMENT NAME self.participant = "participant" # TODO: PP NAME # eye tracker properties self.connected = False self.recording = False self.eye_used = 0 # 0=left, 1=right, 2=binocular self.left_eye = 0 self.right_eye = 1 self.binocular = 2 self.errdist = 2 # degrees; maximal error for drift correction self.maxtries = 100 # number of samples obtained before giving up (for obtaining accuracy and tracker distance information, as well as starting or stopping recording) self.prevsample = (-1, -1) self.prevps = -1 # event detection properties self.fixtresh = 1.5 # degrees; maximal distance from fixation start (if gaze wanders beyond this, fixation has stopped) self.fixtimetresh = 100 # milliseconds; amount of time gaze has to linger within self.fixtresh to be marked as a fixation self.spdtresh = saccade_velocity_threshold # degrees per second; saccade velocity threshold self.accthresh = saccade_acceleration_threshold # degrees per second**2; saccade acceleration threshold self.eventdetection = eventdetection self.set_detection_type(self.eventdetection) self.weightdist = 10 # 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) # set logger res = iViewXAPI.iV_SetLogger(c_int(1), c_char_p(logfile + '_SMILOG.txt')) if res != 1: err = errorstring(res) raise Exception( "Error in libsmi.SMItracker.__init__: failed to set logger; %s" % err) # first logger argument is for logging type (I'm guessing these are decimal bit codes) # LOG status bitcode # 1 = LOG_LEVEL_BUG 00001 # 2 = LOG_LEVEL_iV_FCT 00010 # 4 = LOG_LEVEL_ETCOM 00100 # 8 = LOG_LEVEL_ALL 01000 # 16 = LOG_LEVEL_IV_COMMAND 10000 # these can be used together, using a bitwise or, e.g.: 1|2|4 (bitcode 00111) # connect to iViewX res = iViewXAPI.iV_Connect(c_char_p(ip), c_int(sendport), c_char_p(ip), c_int(receiveport)) if res == 1: res = iViewXAPI.iV_GetSystemInfo(byref(systemData)) self.samplerate = systemData.samplerate self.sampletime = 1000.0 / self.samplerate if res != 1: err = errorstring(res) raise Exception( "Error in libsmi.SMItracker.__init__: failed to get system information; %s" % err) # handle connection errors else: self.connected = False err = errorstring(res) raise Exception( "Error in libsmi.SMItracker.__init__: establishing connection failed; %s" % err) # initiation report self.log("pygaze initiation report start") self.log("experiment: %s" % self.description) self.log("participant: %s" % self.participant) self.log("display resolution: %sx%s" % (self.dispsize[0], self.dispsize[1])) self.log("display size in cm: %sx%s" % (self.screensize[0], self.screensize[1])) self.log("samplerate: %s Hz" % self.samplerate) self.log("sampletime: %s ms" % self.sampletime) self.log("fixation threshold: %s degrees" % self.fixtresh) self.log("speed threshold: %s degrees/second" % self.spdtresh) self.log("acceleration threshold: %s degrees/second**2" % self.accthresh) self.log("pygaze initiation report end")
# create instances # initialize the display disp = Display() # initialize a screen scr = Screen() # initialize an EyeTracker tracker = EyeTracker(disp) # initialize a keyboard kb = Keyboard(keylist=['space'], timeout=None) # initialize a sound snd = Sound(soundfile=soundfile) # initialize a Timer timer = Time() # create a new logfile log = Logfile(filename="test") log.write(["test", "time"]) # # # # # # welcome scr.draw_text("Welcome to the PyGaze Supertest!\n\nYou're going to be testing \ your PyGaze installation today, using this interactive tool. Press Space \ to start!\n\n\nP.S. If you see this, the following functions work: \ \n- Screen.draw_text \
def __init__(self, libeyelink, tracker): """ Constructor. Arguments: libeyelink -- A libeyelink object. tracker -- An tracker object as returned by pylink.EyeLink(). """ pylink.EyeLinkCustomDisplay.__init__(self) # objects self.libeyelink = libeyelink self.display = libeyelink.display self.screen = Screen(disptype=DISPTYPE, mousevisible=False) self.kb = Keyboard(keylist=None, timeout=0) self.mouse = Mouse(timeout=0) if DISPTYPE == 'pygame': self.kb.set_timeout(timeout=0.001) # If we are using a DISPTYPE that cannot be used directly, we have to # save the camera image to a temporary file on each frame. #if DISPTYPE not in ('pygame', 'psychopy'): import tempfile import os self.tmp_file = os.path.join(tempfile.gettempdir(), '__eyelink__.jpg') # drawing properties self.xc = self.display.dispsize[0]/2 self.yc = self.display.dispsize[1]/2 self.extra_info = True self.ld = 40 # line distance self.fontsize = libeyelink.fontsize self.title = "" self.display_open = True # menu self.menuscreen = Screen(disptype=DISPTYPE, mousevisible=False) self.menuscreen.draw_text(text="Eyelink calibration menu", pos=(self.xc,self.yc-6*self.ld), center=True, font='mono', fontsize=int(2*self.fontsize), antialias=True) self.menuscreen.draw_text(text="%s (pygaze %s, pylink %s)" \ % (libeyelink.eyelink_model, pygaze.version, pylink.__version__), pos=(self.xc,self.yc-5*self.ld), center=True, font='mono', fontsize=int(.8*self.fontsize), antialias=True) self.menuscreen.draw_text(text="Press C to calibrate", pos=(self.xc, self.yc-3*self.ld), center=True, font='mono', fontsize=self.fontsize, antialias=True) self.menuscreen.draw_text(text="Press V to validate", pos=(self.xc, self.yc-2*self.ld), center=True, font='mono', fontsize=self.fontsize, antialias=True) self.menuscreen.draw_text(text="Press A to auto-threshold", pos=(self.xc,self.yc-1*self.ld), center=True, font='mono', fontsize=self.fontsize, antialias=True) self.menuscreen.draw_text(text="Press I to toggle extra info in camera image", pos=(self.xc,self.yc-0*self.ld), center=True, font='mono', fontsize=self.fontsize, antialias=True) self.menuscreen.draw_text(text="Press Enter to show camera image", pos=(self.xc,self.yc+1*self.ld), center=True, font='mono', fontsize=self.fontsize, antialias=True) self.menuscreen.draw_text( text="(then change between images using the arrow keys)", pos=(self.xc, self.yc+2*self.ld), center=True, font='mono', fontsize=self.fontsize, antialias=True) self.menuscreen.draw_text(text="Press Escape to abort experiment", pos=(self.xc, self.yc+4*self.ld), center=True, font='mono', fontsize=self.fontsize, antialias=True) self.menuscreen.draw_text(text="Press Q to exit menu", pos=(self.xc, self.yc+5*self.ld), center=True, font='mono', fontsize=self.fontsize, antialias=True) # beeps self.__target_beep__ = Sound(osc='sine', freq=440, length=50, attack=0, decay=0, soundfile=None) self.__target_beep__done__ = Sound(osc='sine', freq=880, length=200, attack=0, decay=0, soundfile=None) self.__target_beep__error__ = Sound(osc='sine', freq=220, length=200, attack=0, decay=0, soundfile=None) # Colors self.color = { pylink.CR_HAIR_COLOR: pygame.Color('white'), pylink.PUPIL_HAIR_COLOR: pygame.Color('white'), pylink.PUPIL_BOX_COLOR: pygame.Color('green'), pylink.SEARCH_LIMIT_BOX_COLOR: pygame.Color('red'), pylink.MOUSE_CURSOR_COLOR: pygame.Color('red'), 'font': pygame.Color('white'), } # Font pygame.font.init() self.font = pygame.font.SysFont('Courier New', 11) # further properties self.state = None self.pal = None self.size = (0,0) self.set_tracker(tracker) self.last_mouse_state = -1 self.bit64 = '64bit' in platform.architecture() self.imagebuffer = self.new_array()
def __init__(self, display, logfile=settings.LOGFILE, \ eventdetection=settings.EVENTDETECTION, \ saccade_velocity_threshold=35, \ saccade_acceleration_threshold=9500, \ blink_threshold=settings.BLINKTHRESH, \ **args): # try to copy docstrings (but ignore it if it fails, as we do # not need it for actual functioning of the code) try: copy_docstr(BaseEyeTracker, EyeLogicTracker) 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 self.disp = display self.screen = Screen() self.dispsize = self.disp.dispsize # display size in pixels self.screensize = settings.SCREENSIZE # display size in cm self.kb = Keyboard(keylist=['space', 'escape', 'q'], timeout=1) self.errorbeep = Sound(osc='saw', freq=100, length=100) # show a message self.screen.clear() self.screen.draw_text( text="Initialising the eye tracker, please wait...", fontsize=20) self.disp.fill(self.screen) self.disp.show() # output file properties self.logfile = logfile # eye tracker properties self._recording = Event() self._recording.clear() self._calibrated = Event() self._calibrated.clear() self.eye_used = 2 # 0=left, 1=right, 2=binocular self.sampleLock = Lock() self.lastSample = None self.maxtries = 100 # number of samples obtained before giving up (for obtaining accuracy and tracker distance information, as well as starting or stopping recording) # event detection properties self.pxfixtresh = 50; self.fixtresh = 1.5 # degrees; maximal distance from fixation start (if gaze wanders beyond this, fixation has stopped) self.fixtimetresh = 100 # milliseconds; amount of time gaze has to linger within self.fixtresh to be marked as a fixation self.spdtresh = saccade_velocity_threshold # degrees per second; saccade velocity threshold self.accthresh = saccade_acceleration_threshold # degrees per second**2; saccade acceleration threshold self.blinkthresh = blink_threshold # milliseconds; blink detection threshold used in PyGaze method self.eventdetection = eventdetection self._log_vars = [ \ "timestampMicroSec", \ "index", \ "porFilteredX", \ "porFilteredY", \ "porLeftX", \ "porLeftY", \ "pupilRadiusLeft", \ "porRightX", \ "porRightY", \ "pupilRadiusRight", \ ] # Open a new log file. dir_name = os.path.dirname(logfile) file_name = os.path.basename(logfile) name, ext = os.path.splitext(file_name) self._data_file_path = os.path.join(dir_name, name+".eyelogic.csv") self._log_file = open(self._data_file_path, "w") # Write a header to the log. header = ["TYPE"] header.extend(self._log_vars) self._sep = ";" self._log_file.write("Sep="+self._sep+"\n") self._log_file.write(self._sep.join(map(str, header))) # Create a lock to prevent simultaneous access to the log file. self._logging_queue = Queue() self._logging_queue_empty = Event() self._logging_queue_empty.set() self._connected = Event() self._connected.set() self._log_counter = 0 self._log_consolidation_freq = 60 self._logging_thread = Thread( target=self.loggingThread, \ name='PyGaze_EyeLogic_Logging', args=[]) global g_api g_api = self # log self.log("pygaze initiation") #self.log("experiment = {}".format(self.description)) #self.log("participant = {}".format(self.participant)) self.log("display resolution = {}x{}".format(self.dispsize[0], \ self.dispsize[1])) self.log("display size in cm = {}x{}".format(self.screensize[0], \ self.screensize[1])) self.log("fixation threshold = {} degrees".format(self.fixtresh)) self.log("speed threshold = {} degrees/second".format(self.spdtresh)) self.log("acceleration threshold = {} degrees/second**2".format( \ self.accthresh)) # connect self.api = ELApi( "PyGaze" ) self.api.registerGazeSampleCallback( gazeSampleCallback ) self.api.registerEventCallback( eventCallback ) resultConnect = self.api.connect() if (resultConnect != ELApi.ReturnConnect.SUCCESS): self._connected.clear() raise Exception("Cannot connect to EyeLogic server = {}".format(errorstringConnect(resultConnect))) self._connected.set() screenConfig = self.api.getScreenConfig() self.log("eye tracker is mounted on screen {}".format(screenConfig.id)) self.rawResolution = (screenConfig.resolutionX, screenConfig.resolutionY) self.log("raw screen resolution = {}x{}".format( self.rawResolution[0], self.rawResolution[1])) self.log("end pygaze initiation") deviceConfig = self.api.getDeviceConfig() if (deviceConfig.deviceSerial == 0): raise Exception("no eye tracking device connected") if (len(deviceConfig.frameRates) == 0): raise Exception("failed to read out device configuration") g_api.sampleRate = deviceConfig.frameRates[0] g_api.sampleTime = 1000.0 / g_api.sampleRate g_api.log("samplerate = {} Hz".format(g_api.sampleRate)) g_api.log("sampletime = {} ms".format(g_api.sampleTime)) self._logging_thread.start() self.screen.clear() self.disp.fill(self.screen) self.disp.show()
def __init__(self, display, logfile=LOGFILE, eventdetection=EVENTDETECTION, \ saccade_velocity_threshold=35, saccade_acceleration_threshold=9500, \ **args): """Initializes the EyeTribeTracker object arguments display -- a pygaze.display.Display instance keyword arguments logfile -- logfile name (string value); note that this is the name for the eye data log file (default = LOGFILE) """ # try to copy docstrings (but ignore it if it fails, as we do # not need it for actual functioning of the code) try: copy_docstr(BaseEyeTracker, EyeTribeTracker) 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 # object properties self.disp = display self.screen = Screen() self.dispsize = DISPSIZE # display size in pixels self.screensize = SCREENSIZE # display size in cm self.kb = Keyboard(keylist=['space', 'escape', 'q'], timeout=1) self.errorbeep = Sound(osc='saw',freq=100, length=100) # output file properties self.outputfile = logfile # eye tracker properties self.connected = False self.recording = False self.errdist = 2 # degrees; maximal error for drift correction self.pxerrdist = 30 # initial error in pixels self.maxtries = 100 # number of samples obtained before giving up (for obtaining accuracy and tracker distance information, as well as starting or stopping recording) self.prevsample = (-1,-1) self.prevps = -1 # event detection properties self.fixtresh = 1.5 # degrees; maximal distance from fixation start (if gaze wanders beyond this, fixation has stopped) self.fixtimetresh = 100 # milliseconds; amount of time gaze has to linger within self.fixtresh to be marked as a fixation self.spdtresh = saccade_velocity_threshold # degrees per second; saccade velocity threshold self.accthresh = saccade_acceleration_threshold # degrees per second**2; saccade acceleration threshold self.eventdetection = eventdetection self.set_detection_type(self.eventdetection) self.weightdist = 10 # 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) # connect to the tracker self.eyetribe = EyeTribe(logfilename=logfile) # get info on the sample rate self.samplerate = self.eyetribe._samplefreq self.sampletime = 1000.0 * self.eyetribe._intsampletime # initiation report self.log("pygaze initiation report start") self.log("display resolution: %sx%s" % (self.dispsize[0],self.dispsize[1])) self.log("display size in cm: %sx%s" % (self.screensize[0],self.screensize[1])) self.log("samplerate: %.2f Hz" % self.samplerate) self.log("sampletime: %.2f ms" % self.sampletime) self.log("fixation threshold: %s degrees" % self.fixtresh) self.log("speed threshold: %s degrees/second" % self.spdtresh) self.log("acceleration threshold: %s degrees/second**2" % self.accthresh) self.log("pygaze initiation report end")
# create instances # initialize the display disp = Display() # initialize a screen scr = Screen() # initialize a keyboard kb = Keyboard(keylist=['space'],timeout=None) # initialize a mouse mouse = Mouse(mousebuttonlist=None, timeout=None) # initialize a sound snd = Sound(osc='sine', freq=4400, length=3000) sounds = { 'a sine wave (slightly oscillating)':Sound(osc='sine', freq=440, length=5000, attack=1000, decay=1000), 'a saw wave':Sound(osc='saw', freq=880, length=5000, attack=0, decay=0), 'a square wave':Sound(osc='square', freq=1760, length=5000, attack=0, decay=0), 'white noise':Sound(osc='whitenoise'), 'soundfile':Sound(soundfile=soundfile) } # initialize a Timer timer = Time() # create a new logfile log = Logfile(filename="test") log.write(["test", "time"])
def __init__(self, display, address='192.168.71.50', udpport=49152, logfile=settings.LOGFILE, eventdetection=settings.EVENTDETECTION, saccade_velocity_threshold=35, saccade_acceleration_threshold=9500, blink_threshold=settings.BLINKTHRESH, **args): """Initializes a TobiiProGlassesTracker instance arguments display -- a pygaze.display.Display instance keyword arguments address -- internal ipv4/ipv6 address for Tobii Pro Glasses 2 (default = '192.168.71.50', for IpV6 address use square brackets [fe80::xxxx:xxxx:xxxx:xxxx]) udpport -- UDP port number for Tobii Pro Glasses data streaming (default = 49152) """ # try to copy docstrings (but ignore it if it fails, as we do # not need it for actual functioning of the code) try: copy_docstr(BaseEyeTracker, TobiiProGlassesTracker) 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 # object properties self.disp = display self.screen = Screen() self.dispsize = settings.DISPSIZE # display size in pixels self.screensize = settings.SCREENSIZE # display size in cm self.screendist = settings.SCREENDIST # distance between participant and screen in cm self.pixpercm = (self.dispsize[0] / float(self.screensize[0]) + self.dispsize[1] / float(self.screensize[1])) / 2.0 self.kb = Keyboard(keylist=['space', 'escape', 'q'], timeout=1) self.errorbeep = Sound(osc='saw', freq=100, length=100) # output file properties self.outputfile = logfile self.description = "experiment" # TODO: EXPERIMENT NAME self.participant = "participant" # TODO: PP NAME # eye tracker properties self.eye_used = 0 # 0=left, 1=right, 2=binocular self.left_eye = 0 self.right_eye = 1 self.binocular = 2 self.maxtries = 100 # number of samples obtained before giving up (for obtaining accuracy and tracker distance information, as well as starting or stopping recording) self.prevsample = (-1, -1) # validation properties self.nvalsamples = 1000 # samples for one validation point # event detection properties self.fixtresh = 1.5 # degrees; maximal distance from fixation start (if gaze wanders beyond this, fixation has stopped) self.fixtimetresh = 100 # milliseconds; amount of time gaze has to linger within self.fixtresh to be marked as a fixation self.spdtresh = saccade_velocity_threshold # degrees per second; saccade velocity threshold self.accthresh = saccade_acceleration_threshold # degrees per second**2; saccade acceleration threshold self.blinkthresh = blink_threshold # milliseconds; blink detection threshold used in PyGaze method self.eventdetection = eventdetection self.set_detection_type(self.eventdetection) self.weightdist = 10 # 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.tobiiglasses = TobiiGlassesController(udpport, address) self.triggers_values = {} self.logging = False self.current_recording_id = None self.current_participant_id = None self.current_project_id = None
def __init__(self, libeyelink, tracker): """ Constructor. Arguments: libeyelink -- A libeyelink object. tracker -- An tracker object as returned by pylink.EyeLink(). """ pylink.EyeLinkCustomDisplay.__init__(self) # objects self.libeyelink = libeyelink self.display = libeyelink.display self.screen = Screen(disptype=settings.DISPTYPE, mousevisible=False) self.kb = Keyboard(keylist=None, timeout=0) self.mouse = Mouse(timeout=0) if settings.DISPTYPE == 'pygame': self.kb.set_timeout(timeout=0.001) # If we are using a DISPTYPE that cannot be used directly, we have to # save the camera image to a temporary file on each frame. #if DISPTYPE not in ('pygame', 'psychopy'): import tempfile import os self.tmp_file = os.path.join(tempfile.gettempdir(), '__eyelink__.jpg') # drawing properties self.xc = self.display.dispsize[0] / 2 self.yc = self.display.dispsize[1] / 2 self.extra_info = True self.ld = 40 # line distance self.fontsize = libeyelink.fontsize self.title = "" self.display_open = True self.draw_menu_screen() # beeps self.__target_beep__ = Sound(osc='sine', freq=440, length=50, attack=0, decay=0, soundfile=None) self.__target_beep__done__ = Sound(osc='sine', freq=880, length=200, attack=0, decay=0, soundfile=None) self.__target_beep__error__ = Sound(osc='sine', freq=220, length=200, attack=0, decay=0, soundfile=None) # Colors self.color = { pylink.CR_HAIR_COLOR: pygame.Color('white'), pylink.PUPIL_HAIR_COLOR: pygame.Color('white'), pylink.PUPIL_BOX_COLOR: pygame.Color('green'), pylink.SEARCH_LIMIT_BOX_COLOR: pygame.Color('red'), pylink.MOUSE_CURSOR_COLOR: pygame.Color('red'), 'font': pygame.Color('white'), } # Font pygame.font.init() self.font = pygame.font.SysFont('Courier New', 11) # further properties self.state = None self.pal = None self.size = (0, 0) self.set_tracker(tracker) self.last_mouse_state = -1 self.bit64 = '64bit' in platform.architecture() self.imagebuffer = self.new_array()
import random from pygaze.display import Display from pygaze.screen import Screen from pygaze.keyboard import Keyboard from pygaze.sound import Sound # create a new Display instance (to interact with the # monitor) disp = Display() # create a new Screen (to use as a canvas to draw on) scr = Screen() # Create two Sounds, one for nice and one for stern # feedback sine = Sound(osc='sine', freq=4000, length=500) noise = Sound(osc='whitenoise', length=500) # a list of vowels vowels = ['a', 'e', 'i', 'o', 'u', 'y'] # create a new Keyboard instance, to monitor key presses kb = Keyboard(keylist=vowels, timeout=None) # randomly choose one vowel letter = random.choice(vowels) # draw the vowel on a Screen scr.draw_text(text=letter, fontsize=128) # fill the Display with a Screen and update the monitor
win.flip() waitKeys() win.flip() wait(2) ## open log for participant data storage log = open(str(pp) + "_data.txt", 'w') log.write("pp\ttrial\tid\toutcome\tdif\tinterim_ability\n") for j in range(trials): ## looking for min dif in ability diflist = abs(ability - dat['difficulty']) index = min((diflist[diflist.index[i]], i) for i in range(len(diflist))) ind = index[1] ## creating sounds snd1 = Sound(osc='sine', freq=dat['sound1'][dat.index[ind]], length=500) snd2 = Sound(osc='sine', freq=dat['sound2'][dat.index[ind]], length=500) win.flip() snd1.play() wait(1) snd2.play() ## indicating answer possibilities stim.draw() win.flip() keys = waitKeys(keyList=['q', 'z', 'slash']) press = keys[0] ## if the same and z then correct, else false. If not the same and z, correct etc. if press == 'q': break elif dat['sound1'][dat.index[ind]] == dat['sound2'][dat.index[ind]]: if press == 'z':
# create instances # initialize the display disp = Display() # initialize a screen scr = Screen() # initialize a keyboard kb = Keyboard(keylist=['space'], timeout=None) # initialize a mouse mouse = Mouse(mousebuttonlist=None, timeout=None) # initialize a sound snd = Sound(osc='sine', freq=4400, length=3000) sounds = { 'a sine wave (slightly oscillating)': Sound(osc='sine', freq=440, length=5000, attack=1000, decay=1000), 'a saw wave': Sound(osc='saw', freq=880, length=5000, attack=0, decay=0), 'a square wave': Sound(osc='square', freq=1760, length=5000, attack=0, decay=0), 'white noise': Sound(osc='whitenoise'), 'soundfile': Sound(soundfile=soundfile) } # initialize a Timer timer = Time()
import pygaze.libtime as timer # Create a new Display instance. disp = Display() # Create a new Keyboard instance. kb = Keyboard() # Create a new Logfile instance. log = Logfile() log.write(["trialnr", "trial_type", "stimulus", \ "fix_onset", "stim_onset", "response", "RT", \ "correct"]) # Create a BAD sound. bad_sound = Sound(osc="whitenoise", length=200) bad_sound.set_volume(1) good_sound = Sound(osc="sine", freq=440, length=200) good_sound.set_volume(0.5) # Create a new Screen instance. scr = Screen() scr.draw_text("Welcome!", fontsize=100, \ colour=(255,100,100)) # Pass the screen to the display. disp.fill(scr) disp.show() timer.pause(3000) # Create a list of all trials.
# Create a colour wheel to select colours from for the stimuli. cw = create_colourwheel(STIML, STIMR, savefile='colourwheel.png') # PYGAZE # Initialise a new Display instance disp = Display() # Initialise a Screen instance for arbitrary drawing. scr = Screen() scr.draw_text(text="Initialising the experiment...", fontsize=FONTSIZE) disp.fill(scr) disp.show() # Initialise the ka-ching sound. kaching = Sound(soundfile=KACHING) # Initialise a Keyboard and a Mouse instance for participant interaction. kb = Keyboard() mouse = Mouse() # COMMUNICATIONS timer.pause(5000) _print("Initialising Client.") # Initialise a new Client instance. client = Client(multicast_ip) # Establish a connection with the server. scr.clear() scr.draw_text(text="Connecting to the server...", fontsize=FONTSIZE) disp.fill(scr)
def __init__(self, libeyelink, tracker): """ Constructor. Arguments: libeyelink -- A libeyelink object. tracker -- An tracker object as returned by pylink.EyeLink(). """ pylink.EyeLinkCustomDisplay.__init__(self) # objects self.libeyelink = libeyelink self.display = libeyelink.display self.screen = Screen(disptype=settings.DISPTYPE, mousevisible=False) self.kb = Keyboard(keylist=None, timeout=1) self.mouse = Mouse(timeout=1) # If we are using a DISPTYPE that cannot be used directly, we have to # save the camera image to a temporary file on each frame. #if DISPTYPE not in ('pygame', 'psychopy'): import tempfile import os self.tmp_file = os.path.join(tempfile.gettempdir(), "__eyelink__.jpg") # drawing properties self.xc = self.display.dispsize[0] / 2 self.yc = self.display.dispsize[1] / 2 self.extra_info = True self.ld = 40 # line distance self.fontsize = libeyelink.fontsize self.title = "" self.display_open = True self.draw_menu_screen() # A crosshair is drawn onto the eye image. This should be scaled in # pylink 1.1.0.5 (tested on Python 2.7) but not on pylink 1.11.0.0 # (tested on Python 3.6). I'm not sure when this change happened, so # it's quite likely we'll have to update the minor version used here. pl_version = pylink.__version__.split(".") if int(pl_version[0]) > 1 or int(pl_version[1]) >= 11: self.scale_lines_in_eye_image = False else: self.scale_lines_in_eye_image = True # Beeps self.__target_beep__ = Sound(osc="sine", freq=440, length=50, attack=0, decay=0, soundfile=None) self.__target_beep__done__ = Sound(osc="sine", freq=880, length=200, attack=0, decay=0, soundfile=None) self.__target_beep__error__ = Sound(osc="sine", freq=220, length=200, attack=0, decay=0, soundfile=None) # Colors self.color = { pylink.CR_HAIR_COLOR: pygame.Color("white"), pylink.PUPIL_HAIR_COLOR: pygame.Color("white"), pylink.PUPIL_BOX_COLOR: pygame.Color("green"), pylink.SEARCH_LIMIT_BOX_COLOR: pygame.Color("red"), pylink.MOUSE_CURSOR_COLOR: pygame.Color("red"), 'font': pygame.Color("white"), } # Font pygame.font.init() self.font = pygame.font.SysFont("Courier New", 11) # further properties self.state = None self.pal = None self.size = (0, 0) self.set_tracker(tracker) self.last_mouse_state = -1 self.bit64 = "64bit" in platform.architecture() self.imagebuffer = self.new_array()