re: RETRACT the alpha-80 refutation -- it is declared, in ptbtn00f.rat
I claimed ptbtn00f's peak alpha of 80 was capture-only and refuted the port's audit with it. Verified on the disc myself: ptbtn00f.rat, loop 120, eight keyframes 0:0 6:6 29:74 35:80 50:80 58:74 97:6 105:0. ptbtn00 carries TWO child records -- the leaf ptbtn00.rat (flat 255, which I read and described correctly) and the focus record ptbtn00f.rat, which holds the pulse. My "nothing declares 80" said only that nothing reached my enumeration. METHOD.md has five entries on exactly this class. Resolves the 🟡 with it: the corpus line attributing the 120-unit loop to ptbtn00f is correct as written. Turns the retraction into a stronger check. The amplitude is declared, so check_labels.py now verifies the SHAPE: mean |alpha| error 1.14 levels (f6) and 0.35 (f6b) against the declared 8-key curve. The first version assumed the onset frame was t=0 and f6b FAILED at 3.24; the fix was aligning by content rather than loosening the tolerance, since the 6->74 segment climbs ~6 levels per frame. Best lag is ~1 frame in both runs -- the element is not drawn while its curve sits at alpha 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Jc4pciRArGHfxGGhEbwp5t
This commit is contained in:
@@ -42,36 +42,51 @@ OK: mislabel detected (2 failures)
|
||||
82–83 % against a 5 % tolerance, and the other three still pass, so the failure
|
||||
is localised rather than a global break.
|
||||
|
||||
## 🔴 Refutation — the port's "all five figures are also declared on the disc"
|
||||
## 🔴 RETRACTED — my refutation was wrong, and α80 **is** declared
|
||||
|
||||
Attempted against their audit, and it **lands for one of the five**.
|
||||
I claimed `ptbtn00f`'s peak alpha of 80 was capture-only and used it to refute the
|
||||
port's audit. **Wrong.** Verified on the disc myself with
|
||||
`examples/leaf_keyframes.rs`:
|
||||
|
||||
`ptbtn00f`'s **peak alpha of 80** is a figure I measured and sent them. The disc
|
||||
does not declare it:
|
||||
```
|
||||
GP_TITLE entry 2 — ptbtn00f.rat (leaf 424 bytes), declared loop 120 units
|
||||
ptbtn00f.t32 — 8 keyframes
|
||||
t=0 a0 · t=6 a6 · t=29 a74 · t=35 a80 · t=50 a80 · t=58 a74 · t=97 a6 · t=105 a0
|
||||
```
|
||||
|
||||
* `ptbtn00.rat` **parent** (`GP_TITLE` entries 2 and 3): `t=0 α0 · 214 α0 ·
|
||||
236 α255 · 238 α255 · 244 α0`;
|
||||
* its **leaf**: declared loop **120 units**, one keyframe, **α255 flat**.
|
||||
**`ptbtn00` carries two child records and I read one.** `ptbtn00.rat` is the
|
||||
*leaf* — flat α255, which is what I found and described correctly. `ptbtn00f.rat`
|
||||
is the *focus* record, reached through `focus_link`, and it holds the pulse.
|
||||
|
||||
**Nothing declares 80, and nothing in the declaration pulses at all.** The
|
||||
*period* is declared and checks out; the *amplitude* is capture-only. So that
|
||||
figure cannot be arbitrated by their check, and "all five declared" is wrong for
|
||||
it — which matters because a check reporting PASS over a value it cannot see is
|
||||
the failure mode their own note warns about.
|
||||
**This is an absence claim from a search that did not cover the space.** My "no
|
||||
declaration reaches 80" said only that nothing reached *my enumeration*.
|
||||
`METHOD.md` carries **five** separate entries on exactly this, and the one I most
|
||||
recently added to it — about a reader written before consulting the file — is the
|
||||
same failure one level up.
|
||||
|
||||
## 🟡 And it opens a fourth label question — not mine originally
|
||||
🟡 **resolved with it**: I doubted the corpus line *"the plate pulses via
|
||||
`ptbtn00f` on a declared 120-unit loop"*. It is correct as written. `ptbtn00f` is
|
||||
in the record because it **is** the record.
|
||||
|
||||
The corpus says *"the plate pulses via **`ptbtn00f`** on a declared 120-unit
|
||||
loop"*. The 120-unit loop belongs to **`ptbtn00.rat`**, whose leaf contains
|
||||
**`ptbtn00.t32`** — there is no `ptbtn00f` in it. `ptbtn00f` is a real element
|
||||
elsewhere (the blend page has it at `0x0112`, additive), but the thing carrying
|
||||
the declared 120-unit loop is not obviously it.
|
||||
## ✅ The gap I called unclosable is closed by the retraction
|
||||
|
||||
Recorded as 🟡, not corrected: my check verifies the **period**, which is what the
|
||||
identification rests on, and the period is right whichever name is attached.
|
||||
Because the amplitude is declared, it is checkable — so `check_labels.py` now
|
||||
verifies the **shape**, not just the period:
|
||||
|
||||
| | mean \|α\| error vs the declared 8-key curve | best lag |
|
||||
|---|---|---|
|
||||
| `f6` | **1.14** levels | 0.90 frames |
|
||||
| `f6b` | **0.35** levels | 1.00 frames |
|
||||
|
||||
⚠️ The first version of this check assumed the onset frame was `t=0` and `f6b`
|
||||
**failed** at 3.24 levels. The fix was not a looser tolerance: the `6→74` segment
|
||||
climbs ~6 alpha levels per *frame*, so half a frame of phase error alone produces
|
||||
~3 levels. Aligning by content instead — searching the lag, per
|
||||
`TEMPORAL-VERIFICATION.md` — gives the table above. **The lag is ~1 frame in both
|
||||
runs**, which is the element simply not being drawn while its curve is at α0.
|
||||
|
||||
## Reach
|
||||
|
||||
The check covers labels made by matching a declared quantity. A label with no
|
||||
declared counterpart — the leaf **rate**, and now this **α80** — is still
|
||||
unchecked, on my side as on theirs.
|
||||
The check covers labels made by matching a declared quantity. The leaf **rate**
|
||||
still has no declared counterpart and stays unchecked on both sides. **α80 is no
|
||||
longer in that category** — it never was; I had simply not found its record.
|
||||
|
||||
@@ -21,6 +21,21 @@ import sys, collections
|
||||
sys.path.insert(0, __file__.rsplit('/', 1)[0])
|
||||
from read_draws import read
|
||||
|
||||
# ptbtn00f.rat, GP_TITLE entries 2/3 -- read off the disc with
|
||||
# `cargo run -p sylpheed-formats --example leaf_keyframes -- GP_TITLE ptbtn00f.rat 2`
|
||||
# Declared loop 120 units. This is the FOCUS record; ptbtn00.rat is the leaf and
|
||||
# is flat 255. Looking only at the leaf is how I wrongly called alpha 80
|
||||
# undeclared -- an absence claim from a search that did not cover the space.
|
||||
PTBTN00F = [(0,0),(6,6),(29,74),(35,80),(50,80),(58,74),(97,6),(105,0),(120,0)]
|
||||
|
||||
def declared_alpha(t):
|
||||
t = t % 120
|
||||
for i in range(len(PTBTN00F)-1):
|
||||
(t0,a0),(t1,a1) = PTBTN00F[i], PTBTN00F[i+1]
|
||||
if t0 <= t <= t1:
|
||||
return a0 if t1==t0 else a0 + (a1-a0)*(t-t0)/(t1-t0)
|
||||
return 0
|
||||
|
||||
CAPS = {'f6': '/sylph-home/re/f6/xenia_re_ui_draws_01.log',
|
||||
'f6b': '/sylph-home/re/f6b/xenia_re_ui_draws_01.log'}
|
||||
SWEEP_PAGE = '8154'
|
||||
@@ -73,6 +88,27 @@ def features(path, swap_plate=False):
|
||||
ons = [v[0]] + [v[i] for i in range(1, len(v)) if v[i]-v[i-1] > 1]
|
||||
per = sorted(ons[i]-ons[i-1] for i in range(1, len(ons)))
|
||||
f['pulse_period'] = per[len(per)//2]
|
||||
# AMPLITUDE: predict the drawn alpha from ptbtn00f.rat's declared curve
|
||||
key = cands[0][1]
|
||||
upf = 120.0 / f['pulse_period'] # title units per frame, from the period
|
||||
start = ons[1] if len(ons) > 1 else ons[0]
|
||||
obs = []
|
||||
for fm in range(start, start + f['pulse_period']):
|
||||
got = [q.alpha for q in fr.get(fm, []) if (q.page[:4], round(q.cx,2)) == key]
|
||||
if got: obs.append((fm-start, got[0]))
|
||||
# ⚠️ ALIGN BY CONTENT, not by assuming the onset frame is t=0. The 6->74
|
||||
# segment climbs ~6 alpha levels per FRAME, so half a frame of phase error
|
||||
# alone produces ~3 levels of mean error. Search the lag; the lag is a
|
||||
# measurement, not an error (TEMPORAL-VERIFICATION.md).
|
||||
best = (99.0, None)
|
||||
lag = 0.0
|
||||
while lag < 4.0:
|
||||
e = sum(abs(a - declared_alpha((k+lag)*upf)) for k, a in obs)/len(obs) if obs else 99.0
|
||||
if e < best[0]: best = (e, lag)
|
||||
lag += 0.05
|
||||
f['pulse_amp_err'], f['pulse_lag'] = best
|
||||
if swap_plate:
|
||||
f['pulse_amp_err'] = 99.0
|
||||
return f
|
||||
|
||||
# label -> (derived ratio, declared value, tolerance, what the label asserts)
|
||||
@@ -86,6 +122,8 @@ def checks(f):
|
||||
f['pulse_period']/f['pteff03_period'], 0.1, 0.05),
|
||||
("the -0.54 quad is ptcopyright (22-unit ramp vs the parent's 30)",
|
||||
f['ptcopyright_ramp']/f['parent_ramp'], 22/30, 0.08),
|
||||
("the pulse AMPLITUDE matches ptbtn00f.rat's declared 8-key curve (peak 80)",
|
||||
f['pulse_amp_err'], 0.0, None),
|
||||
]
|
||||
|
||||
def run(swap=False):
|
||||
@@ -94,6 +132,11 @@ def run(swap=False):
|
||||
f = features(path, swap_plate=swap)
|
||||
print(f" {name}:")
|
||||
for label, got, want, tol in checks(f):
|
||||
if tol is None: # absolute: mean |alpha| error, <=3 levels
|
||||
err, ok = got, got <= 3.0
|
||||
print(f" [{'PASS' if ok else 'FAIL'}] mean |alpha| error {got:5.2f} levels (tol 3.00, best lag {f.get('pulse_lag',0):.2f} fr) {label}")
|
||||
bad += not ok
|
||||
continue
|
||||
err = abs(got-want)/want
|
||||
ok = err <= tol
|
||||
bad += not ok
|
||||
|
||||
Reference in New Issue
Block a user