#!/usr/bin/env python3 """Build preview.html: embedded sample videos per regime + their questions + stats.""" import base64 import csv import json from collections import Counter from pathlib import Path ROOT = Path(__file__).parent / "dataset" REGIME_TITLES = { "train": "TRAIN (in-distribution, matches pendulum-cjepa-160f recipe)", "val_high_damp": "VAL OOD · high damping γ∈(0.55,0.90)", "val_low_damp": "VAL OOD · near-zero damping γ∈(0,0.08)", "val_large_angle": "VAL OOD · large release angle ±(45–80°)", "val_gravity": "VAL OOD · Moon / Mars / Jupiter gravity", "val_quad_damping": "VAL OOD · quadratic drag β·ω|ω| (new law)", "val_driven": "VAL OOD · periodically driven pendulum (new forcing)", } def b64(p): return base64.b64encode(open(p, "rb").read()).decode() def esc(s): return str(s).replace("&", "&").replace("<", "<").replace(">", ">") def main(): idx = list(csv.DictReader(open(ROOT / "index.csv"))) by_regime = {} for r in idx: by_regime.setdefault(r["regime"], []).append(r) qj = {} for split in ("train", "val"): for e in json.load(open(ROOT / "questions" / f"questions_{split}.json"))["scene_annotation"]: qj[e["video_id"]] = e["questions"] stats_type = Counter() stats_concept = Counter() for qs in qj.values(): for q in qs: stats_type[q["question_type"]] += 1 stats_concept[q.get("concept", "?")] += 1 parts = ["""
3,000 videos (160 frames @12 fps, 196×196, H.264) · frame-aligned CSV labels · ~24k questions across the four CLEVRER types. Validation is out-of-distribution physics on purpose (causal generalization), not just a held-out seed. All question answers are derived from the ground-truth RK4 simulation (videos show 13.33 s; a hidden 28 s continuation grounds the predictive questions).
"""] n_q = sum(len(v) for v in qj.values()) parts.append(f"| videos | questions | |
|---|---|---|
| train (in-distribution) | 2400 | — |
| val (6 OOD regimes × 100) | 600 | — |
| total | 3000 | {n_q} |
| question type | count |
|---|---|
| {k} | {v} |
| concept | count |
|---|---|
| {esc(k)} | {v} |
{vid}.mp4 · {esc(params)}