@@ -93,6 +93,79 @@ <h1>Project Journal</h1>
9393 following the format of the entries that follow. Keep newest-first order.
9494 ════════════════════════════════════════════════════════════════════════ -->
9595
96+ <!-- ── GT precision: the stave-height invariant probe ── -->
97+ < article class ="entry ">
98+ < h2 > The stave-height invariant is exact in PDMX but loose in KernSheet — and the slack looks like GT noise</ h2 >
99+ < div class ="entry-meta ">
100+ < span > 2026-06-11</ span >
101+ < span class ="badge deferred "> Finding</ span >
102+ < span class ="ref "> throwaway GT probe · cf. < a href ="staffer-training.html#run-debussy-mixed "> staffer-training</ a > </ span >
103+ </ div >
104+
105+ < h3 > Context</ h3 >
106+ < p >
107+ A standing idea for the staffer: every staff on a printed page is engraved at one rastral
108+ size, so < strong > stave heights within a page should be constant</ strong > — an unused structural
109+ prior we could lean on (a soft height-consistency loss, or even
110+ < code > bottom = top + shared_height</ code > ). Before building anything, the honest first move is
111+ to check the premise < em > in the ground truth itself</ em > . A throwaway script measured the
112+ within-page coefficient of variation (CV = std/mean, scale-free) of stave heights
113+ (< code > box.bottom − box.top</ code > ) on ~400 sampled scores from each of PDMX and KernSheet.
114+ </ p >
115+
116+ < div class ="outcome ">
117+ < strong > PDMX: the invariant is exact.</ strong > Stave-height CV is 0.00% from median through
118+ p99; 99.2% of multi-staff pages sit under a 2% CV (4,869 staves, 646 pages). Verovio renders
119+ every staff identically — within a page the heights are pixel-for-pixel equal.
120+ </ div >
121+ < table >
122+ < thead > < tr > < th > within-page stave height</ th > < th > PDMX (synthetic)</ th > < th > KernSheet (real scans)</ th > </ tr > </ thead >
123+ < tbody >
124+ < tr > < td > CV — median / p90 / p99</ td > < td > 0.00 / 0.00 / 0.00 %</ td > < td > < strong > 2.89 / 6.33 / 10.60 %</ strong > </ td > </ tr >
125+ < tr > < td > (max−min)/mean — median / p99</ td > < td > 0.00 / 0.00 %</ td > < td > < strong > 7.8 / 29.6 %</ strong > </ td > </ tr >
126+ < tr > < td > pages with CV < 2%</ td > < td > 99.2%</ td > < td > 34.0%</ td > </ tr >
127+ < tr > < td > median staff height</ td > < td > 72 px</ td > < td > 45 px</ td > </ tr >
128+ </ tbody >
129+ </ table >
130+
131+ < h3 > The uncomfortable reading</ h3 >
132+ < p >
133+ On KernSheet the invariant is only < em > approximately</ em > true: the median within-page spread
134+ is < strong > 7.8% ≈ 3.5 px on a 45 px staff</ strong > , with a real tail (p99 spread ~30%, ~13 px).
135+ The discomfort is the magnitude — that ~3.5 px is < strong > the same order as the ~3.5 px stave
136+ error the model posts on KernSheet</ strong > . Two facts make the likely cause
137+ < strong > GT imprecision, not the model</ strong > : (1) the rastral size on a flatbed-scanned
138+ printed score is < em > physically</ em > constant, so genuine height variation should be ≈0; (2) the
139+ KernSheet boxes are hand-placed/manually-validated, and the spread we see is exactly what
140+ pixel-level annotation jitter produces. So part of what we've been charging to the detector on
141+ KernSheet may in fact be noise baked into the labels — the GT is less precise than it was
142+ assumed to be.
143+ </ p >
144+ < p >
145+ A secondary structural note fell out of the same probe: even in PDMX, < strong > system</ strong >
146+ heights vary among systems sharing a staff_count (p99 CV 10%) — the variation lives in the
147+ inter-staff gaps, not the staves. So the invariant is a < em > stave</ em > property only; any prior
148+ must target stave heights, never system heights.
149+ </ p >
150+
151+ < h3 > Consequences</ h3 >
152+ < ul >
153+ < li > < strong > A KernSheet stave-error floor.</ strong > If the labels carry ~3.5 px of height
154+ jitter, sub-~3 px stave-error numbers on KernSheet should be read with suspicion — at that
155+ scale we may be measuring annotation noise, not model error. The PDMX numbers stay trustworthy.</ li >
156+ < li > < strong > Hard height-coupling is off the table</ strong > — it would be perfect for PDMX but
157+ would fight whatever real (or noisy) variation KernSheet carries. A < em > soft</ em >
158+ consistency regulariser remains viable and could double as a label denoiser (pulling outlier
159+ box heights toward the page mean), < em > if</ em > the spread is annotation noise rather than
160+ true scan skew.</ li >
161+ < li > < strong > Open question this probe can't settle:</ strong > real scan geometry (skew,
162+ perspective) vs. annotation jitter. On flat printed scans the balance tilts toward
163+ annotation, but it's unconfirmed. A cheap follow-up: a height-consistency check in the
164+ KernSheet editor that flags pages whose stave heights disperse beyond a few percent — both a
165+ QA pass on the existing GT and the experiment that separates the two causes.</ li >
166+ </ ul >
167+ </ article >
168+
96169<!-- ── PDMX-rehearsal mixing to fight KernSheet catastrophic forgetting ── -->
97170< article class ="entry ">
98171 < h2 > Rehearsal mixing: PDMX as a secondary stream in every KernSheet fine-tune</ h2 >
0 commit comments