Experiment API¶
Configuration¶
body_eye_sync.experiment.config
¶
Serialisable definition of an experiment: its inputs and the pipeline to run.
AudioInput
¶
Bases: _Input
Audio recorded on its own device, e.g. a directional microphone.
Embedded audio in video files is handled as part of video playback; this input is for separate audio files.
Source code in src/body_eye_sync/experiment/config.py
BodyPoseStep
¶
Bases: _Model
Per-box body-pose detection. Fields mirror detect_body_poses.
Source code in src/body_eye_sync/experiment/config.py
ExperimentConfig
¶
Bases: _Model
The serialisable definition of an experiment: its inputs and the pipeline to run.
Source code in src/body_eye_sync/experiment/config.py
FaceDetectionStep
¶
Bases: _Model
Per-box face detection. Fields mirror detect_faces.
Source code in src/body_eye_sync/experiment/config.py
FixedVideoInput
¶
GlassesVideoInput
¶
Bases: _Input
Video and gaze data recorded by a participant's glasses-mounted camera.
Source code in src/body_eye_sync/experiment/config.py
ObjectTrackingStep
¶
Bases: _Model
Object detection + ReID tracking. Fields mirror detect_tracklets.
choices in a field's json_schema_extra are suggested values the GUI
offers in an editable combobox; a custom value is still allowed.
Source code in src/body_eye_sync/experiment/config.py
Pipeline
¶
Bases: _Model
What to run for each type of input.
Source code in src/body_eye_sync/experiment/config.py
SpeechPipeline
¶
Bases: StepPipeline
The stages run over all inputs that contain audio.
Transcription is the only one: it says what was said, and who said it is settled afterwards, by comparing the experiment's recordings with each other.
Source code in src/body_eye_sync/experiment/config.py
SpeechPostProcessingSettings
¶
Bases: _Model
How transcripts are combined to form experiment-wide speaker turns.
Source code in src/body_eye_sync/experiment/config.py
StepPipeline
¶
TimelineConfig
¶
Bases: _Model
Where one recording sits on the experiment's shared clock.
Source code in src/body_eye_sync/experiment/config.py
TranscriptionStep
¶
Bases: _Model
Speech transcription. Fields mirror transcribe.
Source code in src/body_eye_sync/experiment/config.py
VideoPipeline
¶
Bases: StepPipeline
The stages run over a video input.
Both video types use this same set of stages, but as independent blocks, so e.g. a room camera can be tracked with a different detector than the glasses cameras.
Source code in src/body_eye_sync/experiment/config.py
validate_input_id(input_id)
¶
Return an input id, having checked it is safe for generated names.
Source code in src/body_eye_sync/experiment/config.py
Runtime Experiment¶
body_eye_sync.experiment.experiment
¶
Experiment contains the loaded inputs, their results and the pipeline to run
Experiment
¶
An experiment: its inputs, their results, and the pipeline to run.
The inputs own their settings, each in the runtime class for its type;
:class:ExperimentConfig is the on-disk form, converted to and from when
the experiment is saved and loaded. Input ids are unique across the types,
and inputs are added, removed and renamed through this class so they stay
that way.
Source code in src/body_eye_sync/experiment/experiment.py
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | |
inputs
property
¶
Every input of every type, for what applies to all of them.
output_dir
property
¶
Where per-input Parquet outputs live, inside the folder.
add_audio(spec)
¶
Add an audio input, returning its :class:Audio.
Raises :class:ValueError if it names a glasses video that is not in
this experiment.
Source code in src/body_eye_sync/experiment/experiment.py
add_fixed_video(spec)
¶
Add a fixed video input, returning its :class:FixedVideo.
Source code in src/body_eye_sync/experiment/experiment.py
add_glasses_video(spec)
¶
Add a glasses video input, returning its :class:GlassesVideo.
Source code in src/body_eye_sync/experiment/experiment.py
config()
¶
The experiment in its on-disk form.
Source code in src/body_eye_sync/experiment/experiment.py
load(folder)
classmethod
¶
Load the experiment in folder: its inputs and their results.
Source code in src/body_eye_sync/experiment/experiment.py
output_dir_for(data)
¶
remove_input(data)
¶
Remove an input from the experiment, leaving its output files alone.
Raises :class:ValueError if it is a glasses video that audio inputs
still refer to.
Source code in src/body_eye_sync/experiment/experiment.py
rename_input(data, new_id)
¶
Give an input a new id, moving its output directory if it exists.
Source code in src/body_eye_sync/experiment/experiment.py
save(folder=None)
¶
Write the experiment, and every input's results, into the folder.
folder defaults to the current :attr:folder and becomes it when
given. The config is always written; an input is written only once it
has results.
Source code in src/body_eye_sync/experiment/experiment.py
Preprocessing Experiments¶
body_eye_sync.experiment.preprocess
¶
Prepare an experiment's inputs for the pipeline, e.g. aligning them and correcting their clock rates.
align_experiment(experiment, *, progress=None)
¶
Measure where each input starts and write the offsets onto the inputs.
Source code in src/body_eye_sync/experiment/preprocess.py
apply_clock_rates(experiment, analysis)
¶
Write an analysis' findings onto the inputs, returning the ids changed.
Significant drift fits replace the whole timeline. Successfully measured inputs without significant drift keep their alignment offset and return to a unit rate, clearing a correction an earlier analysis applied.
Source code in src/body_eye_sync/experiment/preprocess.py
clear_clock_rates(experiment)
¶
Drop every input's clock-rate correction, returning the ids changed.
The offsets are left as they are: those say where each recording starts, which alignment worked out, and are not this correction's to undo.
Source code in src/body_eye_sync/experiment/preprocess.py
has_corrected_clock_rates(experiment)
¶
Whether any input carries a clock-rate correction to clear.
recordings(experiment)
¶
The experiment's inputs that have a recording to measure, keyed by id.
Running Experiments¶
body_eye_sync.experiment.run
¶
Run an :class:~body_eye_sync.experiment.experiment.Experiment non-interactively.
attribute_speech(experiment)
¶
Work out the experiment's speech turns and write them beside the inputs.
Source code in src/body_eye_sync/experiment/run.py
run_audio(experiment, audio)
¶
Run the speech pipeline stages over audio.
Source code in src/body_eye_sync/experiment/run.py
run_experiment(experiment, *, force=False)
¶
Run the whole pipeline over all inputs, returning each one's output directory.
Source code in src/body_eye_sync/experiment/run.py
run_fixed_video(experiment, video)
¶
Run the fixed video pipeline stages over video.
Source code in src/body_eye_sync/experiment/run.py
run_glasses_video(experiment, video)
¶
Run the glasses video pipeline stages over video.
Source code in src/body_eye_sync/experiment/run.py
Input Timelines¶
body_eye_sync.experiment.timeline
¶
Where an input's own clock sits on the shared experiment timeline.
Every recording is made on its own device, which starts whenever that device
was switched on and counts time on its own crystal. Two crystals differ by tens
of parts per million, so a :class:Timeline contains an offset and a rate.
Timeline
dataclass
¶
Conversions between one recording's clock and the experiment's.
Source code in src/body_eye_sync/experiment/timeline.py
corrects_drift
property
¶
Whether this timeline carries a measured clock-rate difference.
drift_ppm
property
¶
How far this recording's clock runs from the experiment's, in ppm.
from_config(config)
classmethod
¶
Build runtime timeline state from its serialisable form.
to_config()
¶
to_experiment_time(local_time)
¶
Experiment time for a moment on this input's own clock.
to_experiment_times(local_times)
¶
Experiment times for an array of moments on this input's clock.
to_local_time(experiment_time)
¶
to_experiment_time(local_time, offset, rate=1.0)
¶
Experiment time for a moment on one recording's own clock.
offset is where the recording starts and rate is how fast its clock
runs against the experiment's. Always defined: every moment the recording's
clock names did happen, whether or not content was captured for it.
Source code in src/body_eye_sync/experiment/timeline.py
to_local_time(experiment_time, offset, rate=1.0)
¶
Where a moment of the experiment sits on one recording's own clock.
Outside the recording's own duration the result is simply out of range; callers that stream a recording check that themselves.
Source code in src/body_eye_sync/experiment/timeline.py
Video Results¶
body_eye_sync.experiment.video
¶
Object tracking and vision model outputs for a video.
FixedVideo
¶
GlassesVideo
¶
Bases: Video
Video and gaze data from a participant's glasses-mounted camera.
Source code in src/body_eye_sync/experiment/video.py
Video
¶
A video input: its settings and the model outputs computed from it.
id names the input and its output directory, and timeline places
the video's own clock on the experiment clock.
Completed results live in a single numeric :attr:data DataFrame. While a
run is in progress, each frame's BoxMOT tracks array is accumulated and
collapsed into that DataFrame once :meth:finish_object_tracking is called.
Face detection runs as a later pass over those tracked boxes, accumulating
per frame and folding its columns onto the matching rows in
:meth:finish_face_detection. Body-pose detection follows the same pattern.
A camera also records audio, so the audio stages can run over this video's
own track, with their results stored in :attr:speech and :attr:loudness.
Source code in src/body_eye_sync/experiment/video.py
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 | |
body_embeddings
property
¶
Best-K body-appearance embeddings per tracklet, or None.
data
property
¶
All tracked detections as a DataFrame, or None until complete.
face_embeddings
property
¶
Best-K face embeddings per tracklet, or None.
add_body_pose_frame(result)
¶
add_face_detection_frame(result)
¶
Accumulate one frame's detected faces for the final merge.
Source code in src/body_eye_sync/experiment/video.py
add_object_tracking_frame(frame)
¶
Accumulate a BoxMOT per-frame result, converting to 0-based indices
Source code in src/body_eye_sync/experiment/video.py
all_boxes_by_frame()
¶
Tracked person boxes grouped by frame, as later passes consume them.
Source code in src/body_eye_sync/experiment/video.py
begin_body_pose_detection(embeddings_per_track=0)
¶
Drop any previous pose columns so a fresh pass starts clean.
embeddings_per_track is accepted for a uniform begin_* signature
across steps but ignored -- pose detection produces no embeddings.
Source code in src/body_eye_sync/experiment/video.py
begin_face_detection(embeddings_per_track=0)
¶
Drop any previous face columns so a fresh pass starts clean.
embeddings_per_track keeps that many best face embeddings per
tracklet, ranked by face score, for later identity clustering.
Source code in src/body_eye_sync/experiment/video.py
begin_object_tracking(embeddings_per_track=0)
¶
Drop any previous model outputs.
embeddings_per_track keeps that many best body-appearance (ReID)
embeddings per tracklet, ranked by detection confidence, for later
identity clustering; 0 keeps none.
Source code in src/body_eye_sync/experiment/video.py
boxes_for_frame(frame_index)
¶
Object bounding boxes for frame frame_index (0-based).
Source code in src/body_eye_sync/experiment/video.py
discard_body_pose_detection()
¶
discard_face_detection()
¶
Drop a cancelled or failed pass; the tracked boxes are left intact.
discard_object_tracking()
¶
faces_for_frame(frame_index)
¶
Detected face boxes for frame frame_index (0-based).
Source code in src/body_eye_sync/experiment/video.py
finish_body_pose_detection()
¶
Merge the streamed poses onto their (frame, track_id) rows.
Source code in src/body_eye_sync/experiment/video.py
finish_face_detection()
¶
Merge the streamed faces onto their (frame, track_id) rows.
Source code in src/body_eye_sync/experiment/video.py
finish_object_tracking()
¶
Collapse the streamed frames into the stored :attr:data DataFrame.
has_audio_track()
¶
Whether this video carries sound
Source code in src/body_eye_sync/experiment/video.py
has_data()
¶
Whether this video has any completed pipeline results in memory.
has_results(directory)
¶
load(directory)
¶
Load results written by :meth:save, if directory holds any.
Source code in src/body_eye_sync/experiment/video.py
poses_for_frame(frame_index)
¶
Detected body poses for frame frame_index (0-based).
Source code in src/body_eye_sync/experiment/video.py
save(directory)
¶
Write these results into directory, one file per kind of result.
Source code in src/body_eye_sync/experiment/video.py
set_data(data)
¶
Replace all results with a complete data DataFrame.
Source code in src/body_eye_sync/experiment/video.py
Audio Results¶
body_eye_sync.experiment.audio
¶
Model outputs for a separately recorded audio input.
Audio
¶
An audio input: its settings and the model outputs computed from it.
Audio recorded on its own device, such as a directional microphone. The inputs carry their own audio separately - meaning embedded audio in video input files is played with the video itself, for example during the Alignment stage.
id names the input and its output directory, and timeline places
the recording's own clock on the experiment clock.
glasses_video is the glasses video worn by the participant this
recording captures, when it is aimed at one.
Source code in src/body_eye_sync/experiment/audio.py
has_audio_track()
¶
has_data()
¶
has_results(directory)
¶
load(directory)
¶
Load results written by :meth:save, if directory holds any.
Replaces any current results. A directory with nothing in it leaves this recording empty rather than failing.
Source code in src/body_eye_sync/experiment/audio.py
save(directory)
¶
Write these results into directory, a file per kind of result.
Source code in src/body_eye_sync/experiment/audio.py
Speech Results¶
body_eye_sync.experiment.speech
¶
A transcription of what was said when in one recording.
Speech
¶
The transcript computed from one recording's audio.
Source code in src/body_eye_sync/experiment/speech.py
data
property
¶
The transcribed segments, or None until transcription has run.
words
property
¶
Per-word timings, or None until transcription has run.
add_transcription_segment(segment)
¶
begin_transcription()
¶
finish_transcription()
¶
Collapse the accumulated segments into :attr:data and :attr:words.
load(directory)
¶
Load results written by :meth:save, if directory holds any.
Source code in src/body_eye_sync/experiment/speech.py
save(directory)
¶
Write these results into directory, one file per kind.
Source code in src/body_eye_sync/experiment/speech.py
set_data(data)
¶
Replace the transcribed segments with a complete data DataFrame.
Source code in src/body_eye_sync/experiment/speech.py
Loudness Results¶
body_eye_sync.experiment.loudness
¶
How loud one recording is over time, computed from its audio.
Loudness
¶
The loudness measured from one recording's audio.
Source code in src/body_eye_sync/experiment/loudness.py
data
property
¶
The measured loudness, or None until the recording is measured.
levels
property
¶
The measured levels in dB, or nothing when this is unmeasured.
times
property
¶
When each level was measured, on the recording's own clock.
load(directory)
¶
Load results written by :meth:save, if directory holds any.
Source code in src/body_eye_sync/experiment/loudness.py
measure(path)
¶
save(directory)
¶
Write these results into directory.
Source code in src/body_eye_sync/experiment/loudness.py
set_data(data)
¶
Replace the measured loudness with a complete data DataFrame.
Source code in src/body_eye_sync/experiment/loudness.py
Embedding Storage¶
body_eye_sync.experiment.embeddings
¶
Storage for the best-K embedding tables the pipeline stages collect.
TopK
¶
Keeps the best-K embeddings per group as float16, ranked by score.
Source code in src/body_eye_sync/experiment/embeddings.py
to_frame()
¶
Best-first table of the kept embeddings, or None if none were kept.
Source code in src/body_eye_sync/experiment/embeddings.py
read_embeddings(path)
¶
Load an embeddings file back into a table of float16 vectors.
write_embeddings(path, table)
¶
Write a best-K embeddings table as fixed-size float16 vectors.
Source code in src/body_eye_sync/experiment/embeddings.py
Speech Turn Results¶
body_eye_sync.experiment.speech_turns
¶
The experiment's speech turns: who spoke when, and what they said.
SpeechTurns
¶
Every speech turn of an experiment, on the shared experiment clock.
Source code in src/body_eye_sync/experiment/speech_turns.py
data
property
¶
The speech turns, or None until they have been worked out.
speakers
property
¶
The inputs speech was attributed to, in the order they are named.
for_speaker(speaker)
¶
One speaker's turns, in the order they spoke them.
Source code in src/body_eye_sync/experiment/speech_turns.py
load(directory)
¶
Load turns written by :meth:save, if directory holds any.
Source code in src/body_eye_sync/experiment/speech_turns.py
save(directory)
¶
Write the turns into directory, or remove them if there are none.
Source code in src/body_eye_sync/experiment/speech_turns.py
set_data(data)
¶
Replace the turns, rejecting overlaps attributed to one speaker.
Source code in src/body_eye_sync/experiment/speech_turns.py
Postprocessing Experiments¶
body_eye_sync.experiment.postprocess
¶
Postprocess an experiment using the pipeline outputs.
attribute_experiment_speech(experiment, *, progress=None)
¶
Work out the experiment's speech turns and store them on it.