Now Shipping! – The EyeLink 3; combined head and eye tracking at up to 1000 Hz.

How-To: EyeLink Data Viewer Integration Messaging Protocol
#1
When running an experiment, it's essential to send messages to the EyeLink Data File (EDF) to mark critical trial events, such as stimulus onset or a participant's response. These messages are crucial for analysis because they allow you to define interest periods and synchronize the gaze data with what happened during the trial.

You can log these messages in a few ways depending on your software:
  • In Experiment Builder: Use the "Message" property of a node or add a separate SEND_MESSAGE node.
  • In other software (e.g., PsychoPy, Psychtoolbox): Send messages via the EyeLink API using the SendMessage() command or a similar function for your programming environment.
Beyond just flagging trial events, you can also send messages formatted specifically for our analysis software, Data Viewer. These "Data Viewer Integration" messages are powerful because they can include trial variables, Interest Area locations, and the file paths for stimuli used in a trial. This information is what enables Data Viewer to create gaze overlay reconstructions.

These integration messages require special formatting, as outlined in the Data Viewer User Manual (in the "Protocol for EyeLink Data to Viewer Integration" section).

The following sections cover the basic messages essential for proper Data Viewer integration. For a practical example, please see our webinar on the EyeLink Data Viewer Integration Messaging Protocol

  1. Trial Parsing Messages

    To parse your data into separate trials, you need to send messages that mark the beginning and end of each trial.

    By default, Data Viewer uses the TRIALID message to signal the start of a trial and the TRIAL_RESULT message to signal its end.

    The examples in the EyeLink Developer's Kit all follow a similar structure. The code below is an abbreviated version from our Psychtoolbox examples; please note that the exact syntax will vary for other programming languages.

    Code:
    % Parse the start of the trial
    Eyelink('Message', 'TRIALID');

    %% -------------
    % your task code
    %% -------------

    % Parse the end of the trial
    Eyelink('Message', 'TRIAL_RESULT 0')

  2. Trial Variables Messages

    Logging task variables and participant responses directly into the EDF file can greatly simplify data analysis. Instead of saving this information in a separate file and merging it with your gaze data later, you can log it during the trial using !V TRIAL_VAR messages.

    Data Viewer is designed to process any message that begins with !V. The TRIAL_VAR message uses a Name = Value format, allowing you to log a variable and its corresponding value on a trial-by-trial basis.

    These variables then appear as additional columns in your Data Viewer reports, which can be used to group and filter trials for aggregate analysis. For example, you can use TRIAL_VAR messages to log the stimulus, participant response, accuracy, and reaction time for each trial.

    Code:
    Eyelink('Message', '!V TRIAL_VAR Stimulus %s', imageFilename)       
    Eyelink('Message', '!V TRIAL_VAR Response %s', subResponse)       
    Eyelink('Message', '!V TRIAL_VAR RT %d', displayOnset-subResponseTime)       
    Eyelink('Message', '!V TRIAL_VAR Accuracy %s', subAccuracy)

    As you can see in the example above, each TRIAL_VAR message should contain a variable name and its corresponding value for that specific trial. If a variable isn't logged on every trial, Data Viewer will automatically insert a placeholder value (a period, ., by default) where it's missing.

    Crucially, these messages must be sent within the trial period—that is, after the TRIALID message and before the TRIAL_RESULT message. Any TRIAL_VAR message sent outside of this window will be ignored by Data Viewer.

  3. Image and Drawing Messages

    You can display the stimulus that was shown to a participant in Data Viewer using special image and drawing commands. These commands create a visual representation of the stimulus in the Spatial Overlay and Animation Playback views.

    These commands use a system where the top-left pixel is (0, 0). For a screen with a 1920x1080 resolution, this means the bottom-right pixel is (1919, 1079), because the coordinates are zero-indexed.

    Display Images via IMGLOAD Messages

    All image-related messages use the !V IMGLOAD command, followed by a subcommand that defines how the image should be displayed. To ensure your project is portable between computers, these commands should use a relative path (the path from the EDF file to the image file).

    For example, to display a full-screen image, use the FILL subcommand. This message tells Data Viewer to load the specified image as a full-screen overlay at the exact time the message is logged.
    Code:
    % The path '../images/myimage.jpg' navigates up one level from the EDF file's location to find the 'images' folder.
    Eyelink('Message', '!V IMGLOAD FILL ../images/myimage.jpg');

    The example below illustrates how to place an image by its top-left corner at pixel (300, 300):
    Code:
    Eyelink('Message', '!V IMGLOAD TOP_LEFT ../images/myimage.jpg 300 300');

    This example centers an image at pixel (400, 400) and resize it to 100x100 pixels:
    Code:
    Eyelink('Message', '!V IMGLOAD CENTER ../images/myimage.jpg 400 400 100 100');

    IMGLOAD Message Syntax
    • Location Type: The location type - TOP_LEFT or CENTER.
    • File Path: The relative path to the image file.
    • Pixel Coordinates: The origin of the image in the screen space.
    • Size (optional): The dimensions of the image.

    Drawing Shapes

    If your stimuli are generated programmatically on the fly (e.g., shapes drawn with code), it's often simpler to send drawing commands to create a placeholder stimulus in Data Viewer.

    Code:
    Eyelink('Message', '!V CLEAR 255 255 255');                        % Clears the display to a white background (R=255, G=255, B=255).
    Eyelink('Message', '!V FILLBOX 0 0 255 400 500 500 600');          % Draws a solid blue box.
    Eyelink('Message', '!V DRAWBOX 0 255 0 200 300 400 500');          % Draws an open (unfilled) green box.
    Eyelink('Message', '!V DRAWLINE 255 0 0 100 100 300 400');         % Draws a red line.

    The Importance of Timing

    For an accurate reconstruction, you must send these image and drawing messages as close to the actual stimulus event as possible.

    In most programming environments, sending the message immediately after the code that presents the stimulus is sufficient for synchronization within <1 ms. If your environment does not allow this, you may need to use a timing offset to align the message and the stimulus, as explained elsewhere in the documentation.

  4. Interest Area Messages

    Instead of defining Interest Areas (IAs) manually in Data Viewer after an experiment, your script can create them automatically during data collection. This is done by sending specially formatted messages that programmatically define each IA's location as your stimuli are presented.

    You can generate several IA shapes using the !V IAREA command:
    • Rectangular IAs:
      Code:
      Eyelink('Message', '!V IAREA RECTANGLE 1 547 410 585 449 square');
    • Elliptical IAs:
      Code:
      Eyelink('Message', '!V IAREA ELLIPSE 2 647 310 685 349 circle');
    • Freehand IAs (Polygons):
      Code:
      Eyelink('Message', '!V IAREA FREEHAND 3 512,284 612,384 512,484 412,384 diamond');

    IA Message Syntax
    • Index: Assign a unique number to each IA. Reusing the same index for different IAs on the same trial can complicate data analysis.
    • Shape: The type of interest area, which can be RECTANGLE, ELLIPSE, or FREEHAND.
    • Pixel Location: The IA's position defined by screen coordinates (X,Y pairs).
      • For rectangles, you only need the coordinates of the top-left and bottom-right corners.
      • For freehand polygons, you must provide a list of all the vertices that form the shape's outline.
    • Label: Give each IA a unique and descriptive text label that clearly identifies the object or region it represents (e.g., "Face," "Target_Object").



  5. Target Position Messages

    In experiments that use a moving target (e.g., pursuit tasks), it's helpful to log the target's position over time. You can do this in Data Viewer by sending TARGET_POS messages.

    These messages define the target's X, Y coordinates at a given time. Once logged, Data Viewer uses this information to calculate the target's position, velocity, and acceleration for each sample in your reports. This data can also be visualized in the Temporal Graph view.

    You can define up to two targets simultaneously using the following syntax:



    Where:
    • <Target1 Key> and <Target2 Key>: the tokens to extract the position(s) of target(s);
    • <(target1 x, target1 y)>> and <(target2 x, target2 y)>: the position(s) of the targets. The coordinates must be enclosed in a pair of brackets;
    • <target 1 visibility> and <target 2 visibility>: if 1, the targets are visible; if 0, the targets are hidden;
    • <target 1 step> and <target 2 step>: if 1, the position of the target will be in steps; if 0, the position of the target is interpolated across samples.

    For example, if you wanted to map the position of a target at pixel (351, 278) in a Matlab task you could use the following message:

    Code:
    Eyelink('Message', '!V TARGET_POS TARG1 (351, 278) 1 0')

    Note: If your target is moving continuously, you must send TARGET_POS messages frequently. Update the target's position either every time it moves or at a rate high enough for Data Viewer's interpolation to accurately reconstruct its path.

  6. Messaging Offset Protocol

    Data Viewer allows you to offset a message's timestamp by preceding the message text with an integer (in milliseconds). This is useful for precisely aligning a message with an event when the message can only be sent slightly before or after it.
    • A positive integer back-stamps the message, making its timestamp earlier.
    • A negative integer forward-stamps the message, making its timestamp later.
    For example, assume a message is received at EDF time 345623:
    • "DISPLAY_ONSET": The message is logged at the exact time it was received, 345623.
    • "16 DISPLAY_ONSET": Data Viewer back-stamps the message by 16 ms, recording it at time 345607 (345623 - 16).
    • "-16 DISPLAY_ONSET": Data Viewer forward-stamps the message by 16 ms, recording it at time 345639 (345623 + 16).