Skip to main content

Regular vs irregular

LABO splits every capture stream into one of two families based on when each row is written. This page is the framework the rest of the Data Streams docs build on. Start here; everything else assumes you know which kind of stream you're looking at.

The idea

  • Regular streams emit a row on a fixed cadence — once per LateUpdate (render frame) or once per FixedUpdate (physics tick). The row rate is determined by the engine's loop, not by what's happening in the experiment. Even if nothing interesting occurred this frame, a row is still written.
  • Irregular streams emit a row only when something specific happens — a variable is updated, an expression is detected, a button is pressed, an agent takes a step. No trigger, no row. The rate is data-driven.

Regular streams

One row per frame or physics tick. Used for continuous signals that always have a value — position, rotation, gaze direction, skeletal pose.

StreamFileWhat it captures
ExperienceStateExperienceState.csvAuthoritative per-frame timeline. Join key for every other file.
ParticipantParticipantTracking.csvCamera pose, controller pose + velocity, grounded flag.
BodyBodyTracking.csvFull-body skeleton joints.
FaceFaceTracking.csvFace-mesh bones / blend-shape-driven skeleton.
HandLeftHandTracking.csv, RightHandTracking.csvLeft and right hand skeletons (two separate files).
EyeEyeTracking.csvCenter / left / right eye positions, directions, gaze data.

All regular streams hook LateUpdate by default. They sample the simulation state at the end of the frame, before rendering.

In action

At 90 Hz, each regular stream produces ~90 rows per second — consistently, whether the participant is moving or sitting still. Ninety rows looks the same whether a stimulus just appeared or the screen is blank.

Irregular streams

One row per trigger. Used for discrete observations that only exist at specific moments — a variable assignment, a detected facial expression, a key press, an agent reward.

StreamFileTrigger
EventsEventPoints.csvEvent-point firing, action execution, epoch transitions.
VariablesVariables.csvEvery variable write (assignment, modification, list update).
ExpressionsExpressions.csvFacial / hand expression detections above threshold.
AgentsAgentsData.csvAgent observations, actions, rewards, episode state.
InputInputCapture.csvKey down / up / hold events for configured keys.
Interactives(see page)Interactive object state changes.

Each stream's writer exposes a public RecordEntry(observation) method that external code calls when the trigger fires. The observation is stamped with the current frame / time / epoch state at that instant via LaboObservation.Stamp(), then queued for the writer.

In action

During a one-minute session a participant presses the spacebar 12 times. InputCapture.csv has 12 rows, one per press event. ParticipantTracking.csv, a regular stream, has ~5400 rows (90 Hz × 60 s) — the 12 button presses are not visible as distinct events in it, only as sudden changes in controller velocity or position.

How to tell which one you need

I want to...Use a...
Track a continuous signal over time (position, gaze, pose)Regular stream
Count discrete occurrences (presses, detections, events)Irregular stream
Align two continuous signalsTwo regular streams joined on FrameNumber
Correlate a discrete event with continuous contextOne irregular + one regular, joined on FrameNumber
Compute a rate (events per second)Irregular for the numerator, session duration for denominator
Compute an average (mean gaze, mean velocity)Regular, grouped by epoch / condition

Shared columns

Every CSV — regular or irregular — starts with the same LaboExperienceState prefix, so any two files can be joined on FrameNumber or MonotonicExecutionTime. Each stream then appends its own domain-specific columns after the shared prefix.

Shared columns, in order:

ObservationTime, MonotonicExecutionTime, FixedIntervalNumber, FrameNumber,
EventNumber, EpochNumber, EpochName, FrameTime, FixedIntervalTime

See Column conventions for the full table and semantics.

Terminology

  • ✅ "regular" / "irregular" — the categories on this page.
  • ✅ "trigger" / "the trigger fires" — what causes an irregular row to be emitted.
  • ❌ "event-driven" — ambiguous with EventPoints.csv / EventNumber; don't use.
  • ❌ "behavioural data" — historical grouping that confusingly excluded ExperienceState / Participant. Don't use.

Further reading