dataforth(datasheet): Fix 2 — per-model slot maps resolve ambiguous DSCA layouts
Some DSCA subtypes' raw_data STATUS groups carry more (or fewer) value-bearing entries than the template's spec-bearing rows (the test program measures slots the printed sheet omits, e.g. DSCA49's 5mA load pair), so the in-order zip misaligned values and those models were skipped by the count-guard. New tool derive-dsca-slotmaps.js derives a per-model slotMap (absolute statusEntries index per spec-bearing row) by greedily matching a staged original's printed values to the DB raw_data STATUS entries (same fround formatting), then picking the candidate map that validates against the most units. Models are grouped by identical row-name signature and one map is derived per group from all sibling units — this disambiguates duplicate values (e.g. a unit where 5mA != 50mA linearity forces the correct slot; DSCA49-04 alone has only 2 staged units that can't, but its siblings' 25 units do). Stored as `slotMap` in dsca-templates.json. Renderer: consults slotMap only when the sequential zip fails (value count != spec-row count), so the 88 already-clean models keep their path (no regression) and ambiguous ones pull the right value via the map. STAGE 3 re-validation: FINAL-TEST CLEAN 88 -> 92; 134 more certs now render (null 450 -> 316); matches 2278 -> 2412. Same 6 retest-vintage dirty models, no new mismatches. DSCA49 family + DSCA40-03 group now clean and validated. Still blocked (separate gap, NOT layout ambiguity): DSCA45-* and most DSCA33-* render null because they have NO spec-reader entries (render-datasheet bails before rendering). Their slotMaps are derived and ready; they need spec coverage. One DSCA33 group (DSCA33-02/03/03A/04/05/1948) did not reach the slotMap validation threshold (best 19/35 units) and stays skipped pending more/cleaner staged samples. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -656,12 +656,15 @@ function generateExactDatasheet(record, specs) {
|
||||
if (m) measurements.push(m);
|
||||
}
|
||||
const specRowCount = dscaTpl.rows.filter(r => (r.spec || '').trim()).length;
|
||||
// The simple positional zip is only sound when there is exactly one measured
|
||||
// value per spec-bearing row. When counts differ, this subtype uses a slot
|
||||
// layout the zip can't resolve (e.g. raw_data records load points the template
|
||||
// omits), so emitting would misalign values onto wrong rows. Skip and flag for
|
||||
// STAGE 3 per-subtype mapping rather than publish wrong data ("do not guess").
|
||||
if (measurements.length !== specRowCount) return null;
|
||||
// The simple positional zip is sound only when there is exactly one measured
|
||||
// value per spec-bearing row. When counts differ, this subtype measures slots
|
||||
// the template omits (e.g. an extra load pair); use the per-model slotMap
|
||||
// (absolute statusEntries index per spec-bearing row, derived from the staged
|
||||
// originals) to pull the right value. With no usable slotMap, skip rather than
|
||||
// misalign ("do not guess").
|
||||
const useSlot = (measurements.length !== specRowCount)
|
||||
&& Array.isArray(dscaTpl.slotMap) && dscaTpl.slotMap.length === specRowCount;
|
||||
if (measurements.length !== specRowCount && !useSlot) return null;
|
||||
|
||||
let h1 = setCol('', 12, 'Parameter');
|
||||
h1 = setCol(h1, 31, 'Measured Value*');
|
||||
@@ -674,13 +677,15 @@ function generateExactDatasheet(record, specs) {
|
||||
h2 = setCol(h2, 69, '='.repeat(6));
|
||||
lines.push(h2);
|
||||
|
||||
let mi = 0;
|
||||
let mi = 0, si = 0;
|
||||
for (const row of dscaTpl.rows) {
|
||||
const spec = (row.spec || '').trim();
|
||||
let line = setCol('', 4, row.name);
|
||||
if (spec) {
|
||||
const su = splitSpecUnit(spec);
|
||||
const m = measurements[mi++];
|
||||
const m = useSlot
|
||||
? formatMeasuredExact(parsed.statusEntries[dscaTpl.slotMap[si++]])
|
||||
: measurements[mi++];
|
||||
if (m) {
|
||||
// measured value right-justified ending at col 38, unit at col 40
|
||||
const v = String(m.valStr);
|
||||
|
||||
Reference in New Issue
Block a user