TrialManager Class

PUBLIC

The TrialManager class is the core component of the GazeTracking system. It orchestrates the entire experiment workflow, including participant initialization, WebGazer setup, calibration, trial execution, gaze data collection, and data export.

Constructor

TrialManager(participantId)

PUBLIC
constructor(participantId = 0)

Creates a new instance of TrialManager. Initializes all necessary properties including Kalman filters for gaze smoothing, head pose tracking variables, and experiment state management.

Parameters

participantId (number, optional)

Unique identifier for the participant. Used for seeded randomization and data tracking. Default: 0

Example

const manager = new TrialManager(12345);
// Creates a new trial manager for participant 12345

Core Properties

Property Type Description
participantId number Unique identifier for the current participant
trialData Array Collection of all trial results including timing, objects shown, and gaze data
currentTrial number Index of the currently executing trial (0-based)
trialCount number Total number of trials to execute (user-specified: 10-50)
calibrationComplete boolean Flag indicating whether initial calibration has been successfully completed
allGazeData Array Complete collection of all gaze points across entire session
testType string Type of stimulus ('Shapes', 'Colors', 'Abstract', 'Pictures')
userInitials string Participant initials (max 6 characters) for file naming

Initialization Methods

initializeExperiment()

PUBLIC
export function initializeExperiment(): void

Top-level initialization function that sets up the entire experiment. Attaches a keydown event listener to start the experiment when any key is pressed. Orchestrates the sequential setup: participant dialog → image loading → WebGazer initialization → calibration.

Workflow

  1. Listen for keydown event (user trigger)
  2. Show participant initials dialog
  3. Parallel: Load images + Initialize WebGazer
  4. Start calibration phase
  5. Begin experiment trials

Example

import { initializeExperiment } from './trialManager.js';

document.addEventListener('DOMContentLoaded', () => {
    initializeExperiment();
    console.log('Ready - press any key to start');
});

showInitialsDialog()

ASYNC
async showInitialsDialog(): Promise<void>

Displays a modal dialog for collecting participant information: initials (max 6 chars), test type (Shapes/Colors/Abstract/Pictures), and trial count (10-50). Validates input before proceeding.

Returns

Promise<void> - Resolves when dialog is submitted with valid inputs

Side Effects

  • Sets this.userInitials
  • Sets this.testType
  • Sets this.trialCount
  • Calls initializeExclusions()
  • Calls setupImages()

initWebGazer()

ASYNC
async initWebGazer(): Promise<void>

Initializes the WebGazer library with enhanced configuration for improved accuracy and head movement resistance. Configures TFFacemesh tracker, ridge regression, adaptive sampling, and gaze listener.

Configuration Applied

Setting Value Reason
Regression Model ridge More stable than weightedRidge for head movement
Tracker TFFacemesh 468-point facial landmark tracking
Storing Points 200 Increased from default 150 for better model
Gaze Listener Custom with adaptive sampling 30-60fps based on movement speed

Example

await trialManager.initWebGazer();
console.log('WebGazer initialized with enhanced features');

Calibration System

startCalibrationPhase()

ASYNC
async startCalibrationPhase(): Promise<void>

Executes the calibration sequence with automatic quality validation and refinement. Displays 9 calibration points in a grid pattern, validates accuracy, and adds refinement points if needed.

Calibration Points

// 9-point grid pattern (percentage-based positioning)
[
  { x: 0.1, y: 0.1 },  // Top-left
  { x: 0.5, y: 0.1 },  // Top-center
  { x: 0.9, y: 0.1 },  // Top-right
  { x: 0.9, y: 0.5 },  // Middle-right
  { x: 0.5, y: 0.5 },  // Center
  { x: 0.1, y: 0.5 },  // Middle-left
  { x: 0.1, y: 0.9 },  // Bottom-left
  { x: 0.5, y: 0.9 },  // Bottom-center
  { x: 0.9, y: 0.9 }   // Bottom-right
]

Validation Process

  1. Complete 9-point calibration
  2. Test predictions at 5 validation points
  3. Calculate quality score (0-1)
  4. If quality < 0.75: add 3 refinement points
  5. Mark calibration complete

validateCalibration()

ASYNC
async validateCalibration(): Promise<number>

Tests calibration quality by measuring prediction error at 5 known points. Returns a normalized quality score between 0 (poor) and 1 (excellent).

Returns

Promise<number> - Quality score: 1 - (avgError / 200), where avgError is mean pixel distance from target points

Quality Threshold

A score ≥ 0.75 indicates acceptable calibration quality. Lower scores trigger automatic refinement with additional calibration points.

quickRecalibration()

ASYNC
async quickRecalibration(): Promise<void>

Performs a fast 3-point recalibration during experiments to maintain accuracy. Called automatically every 10 trials. Uses center and corner points for quick adjustment.

Recalibration Points

// 3-point quick recalibration
[
  { x: 0.5, y: 0.5 },  // Center
  { x: 0.1, y: 0.1 },  // Top-left
  { x: 0.9, y: 0.9 }   // Bottom-right
]

Gaze Tracking Methods

processGazeData(gazePoint, trialStartTime)

PUBLIC
processGazeData(gazePoint: Object, trialStartTime: number): void

Core gaze processing pipeline. Applies outlier detection, head pose compensation, Kalman filtering, and stores enhanced gaze data with metadata. This is the heart of the eye tracking system.

Parameters

gazePoint (Object)

Raw gaze coordinates from WebGazer: {x: number, y: number}

trialStartTime (number)

Timestamp when current trial started (milliseconds since epoch)

Processing Pipeline

  1. Outlier Detection: Reject if >500px jump or off-screen (+100px buffer)
  2. Head Pose Extraction: Get roll, pitch, yaw from facial landmarks
  3. Kalman Filtering: Apply smoothing with q=0.01, r=0.1
  4. Data Enrichment: Add metadata (timestamps, phase, head pose)
  5. Buffer Management: Update recent points (max 5) for outlier detection
  6. Storage: Add to current trial and all-gaze-data arrays

Output Format

{
  x: 512.3,              // Filtered gaze X (pixels)
  y: 384.7,              // Filtered gaze Y (pixels)
  rawX: 515.1,           // Raw gaze X (pixels)
  rawY: 388.2,           // Raw gaze Y (pixels)
  headPose: {
    roll: 0.05,          // Roll angle (radians, relative to baseline)
    pitch: -0.02,        // Pitch angle (radians)
    yaw: 0.08,           // Yaw angle (radians)
    distance: 125.4      // Face distance metric
  },
  time: 1706284847123,   // Absolute timestamp (ms)
  relativeTime: 2543,    // Time since trial start (ms)
  phase: 'experiment'    // 'calibration' or 'experiment'
}

initKalmanFilter()

PUBLIC
initKalmanFilter(): void

Initializes Kalman filter states for X and Y coordinates. Sets process noise (q), measurement noise (r), estimation error (p), estimated value (x), and Kalman gain (k).

Filter Parameters

Parameter Value Description
q (process noise) 0.01 Model uncertainty - lower = trust model more
r (measurement noise) 0.1 Sensor uncertainty - lower = trust measurements more
p (estimation error) 1 Initial uncertainty estimate
x (estimated value) 0 Initial filtered coordinate
k (Kalman gain) 0 Computed gain for optimal filtering
Tuning Tip: These parameters were optimized through empirical testing. Lower q/r ratios provide more smoothing but increase lag. Current values balance accuracy and responsiveness.

See Also