re: settle_time measured -- the title is drawn at 2 s, not at rest.t s 4.18
The port s boot sequencer paces every screen off rest.t, which is the last hold keyframe rather than when a screen arrives. Measured on one cold boot: the container had no Xenia storage root at all, so this is a fresh profile with no shader cache, the slowest case. title build-in (first ink -> art fully drawn) 0.23 s title settled -> PRESS A plate on 2.247 s (disc declares 120 units) plate pulse period ~2.37 s main menu build-in 0.531 s B -> title 0.482 s A -> menu 3.763 s DO NOT AUTHOR, see below The title s rest.t is 251 units = 4.183 s and its art is finished at about 2 s, so a sequencer pacing off rest.t holds it roughly twice as long as the game does. Instrument controlled before the run: 9/9 on the content classifier including the movie-frame and difficulty-screen negatives, 4/4 on the plate detector; the run sampled 7.99 fps against a requested 8 with an independent one-shot grab cross-checking every 20 s. Records a refutation attempt of mine that FAILED. The probe s own marks gave a plate delay of 3.203 s against the corpus s 2.13 s, which on a cold-cache boot looked like a real effect. It was the instrument: the plate pulse period is an internal clock for presentation rate and measures 2.369 s here against the corpus s 2.3, so the run is not slowed, and re-measuring from content gives 2.247 s. The probe s title_static mark fires during the crossfade out of the attract movie, before the wordmark has drawn -- glyph was still 0 when it fired. Also a third independent reproduction of the A-path load stall: 13 frames, 1.53 s, surface mean 26.631 against the earlier 14/1.53 and 12/1.39 at 26.626. This boot had no shader cache, so it is not a warm-cache artefact. Noted that the earlier pair agreed to six decimals and mine agrees to three. Reach: one run. The menu build-in and B->title rest on it alone. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QsEPXWVaEpyfudtR6re1Pd
This commit is contained in:
81
tools/re-capture/settle_analyse.py
Executable file
81
tools/re-capture/settle_analyse.py
Executable file
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Offline: when does each screen ARRIVE, and when does it SETTLE?
|
||||
|
||||
`rest.t` is the last hold keyframe, not when a screen stops moving -- the port
|
||||
paces its boot sequencer off it and is late. This reads the timing probe's TSV
|
||||
and reports, per screen segment:
|
||||
|
||||
arrive first frame the classifier labels that screen
|
||||
settle first frame after `arrive` where inter-frame motion stays below the
|
||||
quiet threshold for SETTLE_HOLD consecutive frames
|
||||
dwell how long the label persists
|
||||
|
||||
The quiet threshold is CALIBRATED FROM THE RUN, not assumed: it is a multiple of
|
||||
the motion floor observed while a label is stable and late in its segment.
|
||||
"""
|
||||
import sys
|
||||
import numpy as np
|
||||
|
||||
SETTLE_HOLD = 4 # consecutive quiet frames before calling it settled
|
||||
|
||||
def main(path):
|
||||
rows = []
|
||||
meta = []
|
||||
for ln in open(path):
|
||||
if ln.startswith("#"):
|
||||
meta.append(ln.rstrip())
|
||||
continue
|
||||
f = ln.rstrip("\n").split("\t")
|
||||
if len(f) < 8:
|
||||
continue
|
||||
rows.append((float(f[0]), int(f[1]), float(f[2]), float(f[3]), f[7]))
|
||||
if not rows:
|
||||
print("no data rows"); return 2
|
||||
t = np.array([r[0] for r in rows])
|
||||
motion = np.array([r[3] for r in rows])
|
||||
labels = [r[4] for r in rows]
|
||||
n = len(rows)
|
||||
fps = n / (t[-1] - t[0]) if t[-1] > t[0] else 0
|
||||
print(f"{n} frames, {t[-1]-t[0]:.1f} s, {fps:.2f} fps")
|
||||
for m in meta:
|
||||
if m.startswith("#summary") or m.startswith("#event"):
|
||||
print(" " + m)
|
||||
|
||||
valid = motion[motion >= 0]
|
||||
if valid.size == 0:
|
||||
print("no motion data"); return 2
|
||||
floor = float(np.percentile(valid, 10))
|
||||
quiet = max(floor * 3.0, 0.05)
|
||||
print(f"\nmotion floor (10th pct) {floor:.4f} -> quiet threshold {quiet:.4f}")
|
||||
|
||||
# Segment by contiguous label.
|
||||
segs = []
|
||||
i = 0
|
||||
while i < n:
|
||||
j = i
|
||||
while j + 1 < n and labels[j + 1] == labels[i]:
|
||||
j += 1
|
||||
segs.append((labels[i], i, j))
|
||||
i = j + 1
|
||||
|
||||
print(f"\n{'screen':<14} {'arrive':>8} {'settle':>8} {'build-in':>9} {'leaves':>8} {'dwell':>8} {'frames':>7}")
|
||||
for lab, a, b in segs:
|
||||
if b - a < 2:
|
||||
continue
|
||||
settle = None
|
||||
run = 0
|
||||
for k in range(a, b + 1):
|
||||
if 0 <= motion[k] < quiet:
|
||||
run += 1
|
||||
if run >= SETTLE_HOLD:
|
||||
settle = t[k - SETTLE_HOLD + 1]
|
||||
break
|
||||
else:
|
||||
run = 0
|
||||
build = f"{settle - t[a]:9.3f}" if settle is not None else " -"
|
||||
s = f"{settle:8.3f}" if settle is not None else " -"
|
||||
print(f"{lab:<14} {t[a]:8.3f} {s} {build} {t[b]:8.3f} {t[b]-t[a]:8.3f} {b-a+1:7d}")
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main(sys.argv[1]))
|
||||
Reference in New Issue
Block a user