Skip to content

Commit 14016ec

Browse files
committed
docs: require reference-validated LMS evaluator
Replace tail-stabilization framing with benchmarked observer data, error thresholds, and range-extreme correctness across roadmap and fundamentals plans.
1 parent cec50a5 commit 14016ec

4 files changed

Lines changed: 61 additions & 31 deletions

File tree

_docs/Roadmap.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ Aligned with the **recommended next order** in [`surface-constraint-gamut-projec
4747

4848
1. **Color-space role cleanup** — reflect the three-role model in UI/docs: Active gamut = working/export intent, World space = layout/interpolation coordinate system, Display gamut = physical display capability. Includes a planned **global Color Context** surface: move Active gamut and Display gamut/profile selection out of the Explorer pipeline when chromatic adaptation / display-gamut work gives that surface real behavior. The Explorer lane keeps reference shell and future Explorer display-gamut clipping/mapping controls. Also documents that `srgbLin` already **is** the gamut-independent colorimetric anchor (linear sRGB ↔ XYZ D65 is a fixed bijection); the proposed XYZ-D65 source-storage migration is **deferred** (representational relabeling, not a correctness fix — not worth a schema break). See [`color-space-role-architecture.md`](color-space-role-architecture.md).
4949
2. **White point & chromatic adaptation** — add a standard CAT (Bradford) wherever whites differ, for active color spaces and the display gamut; D65↔D65 stays a no-op. Today there is **no** adaptation, so non-D65 gamuts (NTSC = Illuminant C, CIE = Illuminant E) and any calibrated display white render wrong. Put the adaptation matrix in the shared `DerivedMatrices` bundle for CPU/GPU/picking parity.
50-
3. **Observer fundamentals & chromaticity registry**stabilize the current LMS/spectral tails, then add table-backed LMS/CMF and chromaticity-diagram registries. This supports the LMS/spectrum panels, spectral locus overlays, direct xy picking, future display-gamut diagnostics, and CVD parity. Tail stabilization can ship without a schema bump; user-selectable observer models belong to the global Color Context only after CVD/panel parity is ready. **Plan:** [`lms-fundamentals-chromaticity-plan.md`](lms-fundamentals-chromaticity-plan.md).
50+
3. **Observer fundamentals & chromaticity registry**audit the current LMS/spectral evaluator against authoritative observer data, keep or replace analytical segments based on measured error, then add LMS/CMF and chromaticity-diagram registries. This supports the LMS/spectrum panels, spectral locus overlays, direct xy picking, future display-gamut diagnostics, and CVD parity. The evaluator correction can ship without a schema bump while the observer identity stays the same; user-selectable observer models belong to the global Color Context only after CVD/panel parity is ready. **Plan:** [`lms-fundamentals-chromaticity-plan.md`](lms-fundamentals-chromaticity-plan.md).
5151
4. **Per-list ramp pipeline instances** — each source list owns its own interpolation, placement, extension, and constraint settings (the engine already computes per-list rows; the settings are still global). The architecture payoff; needs a schema bump (v12 → v13). **Plan:** [`per-list-pipeline-plan.md`](per-list-pipeline-plan.md).
5252
5. **Separate main-curve and extension constraints** — Interpolate constraints and Extend/Expand constraints independently configurable, per source list. Batched into #4's schema bump (see plan); wiring lands in a later phase.
5353
6. **Display gamut preferences + Color Context UI** — store display profiles/calibration in `localStorage`; users may have multiple displays. Initial default remains sRGB. Depends on #2 for correct white handling and should share the global Color Context surface with future observer/fundamentals settings from #3. This is the preferred moment to move Display gamut out of the Explorer pipeline.
@@ -121,7 +121,7 @@ Key points:
121121

122122
- source lists stay in `srgbLin`, documented as the canonical gamut-independent colorimetric anchor (≡ XYZ D65); the XYZ-D65 migration is **deferred** (representational only);
123123
- add chromatic adaptation (Bradford) for non-D65 active/display whites — currently absent;
124-
- stabilize LMS fundamentals / spectral locus tails and add an observer + chromaticity-diagram registry before relying on advanced spectral/chromaticity diagnostics;
124+
- audit and correct the current LMS/spectral evaluator against authoritative reference data, then add an observer + chromaticity-diagram registry before relying on advanced spectral/chromaticity diagnostics;
125125
- Display gamut profiles live in `localStorage`, not shared document state;
126126
- Active gamut and Display gamut should become global Color Context controls, not Explorer pipeline controls; Explorer keeps reference shell and display-mapping/clipping controls;
127127
- each source list owns independent pipeline settings (per-list pipelines) — the next architecture build, behind a schema bump (see [`per-list-pipeline-plan.md`](per-list-pipeline-plan.md));
@@ -165,10 +165,10 @@ Open question: should neutral backdrop apply only inside the WebGL canvas letter
165165
| Custom Display Gamut | Wizard UX design before implementation |
166166
| Gradient designer improvements | Builds on existing ramp model |
167167
| Okhsl/Okhsv picker coordinates | Sliders for selected stop only |
168-
| Observer fundamentals + chromaticity diagrams | Stable LMS/spectral locus registry; see `lms-fundamentals-chromaticity-plan.md` |
168+
| Observer fundamentals + chromaticity diagrams | Reference-validated LMS/spectral evaluator and diagram registry; see `lms-fundamentals-chromaticity-plan.md` |
169169
| Direct xy chromaticity picking | Needs luminance hold policy and active diagram/observer semantics |
170170
| Gamut boundary snap tools | Stop-level UX on top of boundary projection |
171-
| Spectral/chromaticity intensity volume | Optional reference layer; depends on stable observer/fundamentals registry |
171+
| Spectral/chromaticity intensity volume | Optional reference layer; depends on reference-validated observer/fundamentals registry |
172172

173173
Full rationale: [`design-review-unimplemented-features.md`](design-review-unimplemented-features.md).
174174

_docs/color-space-role-architecture.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,11 @@ math, and future chromaticity picking/reference layers.
192192

193193
Recommended sequencing:
194194

195-
1. First, stabilize the current default fundamentals implementation
196-
(table/spline-backed tails) without changing document schema or exposing new
197-
user settings.
198-
2. Next, add `fundamentals.ts` / `diagrams.ts` registries behind the existing
195+
1. First, audit the current default analytical fundamentals evaluator against
196+
authoritative reference data, keeping accurate analytical segments and
197+
replacing only the regions/methods that fail error or tail-behavior criteria.
198+
This does not require document schema changes or new user settings.
199+
2. Next, add `fundamentals.ts` / `diagrams.ts` registries behind the corrected
199200
default behavior.
200201
3. Expose a chromaticity diagram selector in Explorer Reference / instrument UI
201202
if it only changes the panel projection.

_docs/lms-fundamentals-chromaticity-plan.md

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Specification & Plan: Modular LMS Cone Fundamentals & Chromaticity Diagrams
22

3-
This specification outlines the modularization of **LMS Cone Fundamentals** and the implementation of **Multiple Chromaticity Diagrams** in COLOR LAB. It addresses the tail divergence of the current analytical fits, maps the user's custom curve to its experimental origins, and details the impact on active and planned color pipelines.
3+
This specification outlines the modularization of **LMS Cone Fundamentals** and the implementation of **Multiple Chromaticity Diagrams** in COLOR LAB. It replaces the current analytical wavelength fits with reference observer data as the source of truth, maps the user's custom curve to its experimental origins, and details the impact on active and planned color pipelines.
44

55
---
66

@@ -48,10 +48,29 @@ Each fundamental model will define:
4848
2. **Stockman & Sharpe (2000) 10°**: Large-field physiological model.
4949
3. **Smith & Pokorny (1975)**: Derived from the Judd-modified CIE 1931 CMFs.
5050

51-
#### Resolving Tail Instability:
52-
To achieve stable analytical evaluation down to 380nm and up to 780nm, we will support two approaches:
53-
- **Cubic Spline Interpolation**: Read official 1nm/5nm tables from CVRL and perform natural cubic spline interpolation. This is mathematically analytical, matches the experimental data exactly, decays naturally to zero, and is highly stable.
54-
- **Asymmetrical Gaussian/Log-Normal Models**: If a closed-form formula is preferred, replace the Gaussian-derivative fits with an asymmetrical log-normal formulation (e.g., the Govardovskii template) that guarantees asymptotic decay to zero at the bounds.
51+
#### Reference-Validated Evaluator Requirement
52+
The first implementation must not hide the current edge artifacts by clamping,
53+
windowing, or otherwise cosmetically stabilizing an evaluator that is wrong at
54+
the edges. Range extremes are colorimetrically meaningful for spectral locus and
55+
observer work, so the evaluator must be validated against authoritative
56+
measured/tabulated data across the full visible range.
57+
58+
Recommended approach:
59+
60+
- Use CVRL / CIE-published table data for the selected observer model at the
61+
finest practical wavelength interval available as the benchmark.
62+
- Evaluate both table-based interpolation and continuous analytical fits against
63+
that benchmark. A good continuous fit can be preferable between tabulated
64+
samples if its error is lower than interpolation and it behaves correctly at
65+
the extremes.
66+
- For interpolation, prefer monotone or shape-preserving methods where possible.
67+
Natural cubic splines are acceptable only if they do not overshoot low-energy
68+
tails or create negative lobes.
69+
- For analytical fits, require explicit error thresholds, correct non-negative
70+
tail behavior, and no oscillation/divergence outside the fitted core range.
71+
- Keep the current analytical fit as a candidate/comparison fixture. If it is
72+
within acceptable error over a documented subrange, keep using it there and
73+
replace only the failing region with a better reference-validated evaluator.
5574

5675
### B. Chromaticity Diagrams (`fe/src/lib/color/diagrams.ts`)
5776
Each diagram defines:
@@ -117,17 +136,20 @@ This means the UI should not introduce a ramp-local or theme-local
117136
Recommended split:
118137

119138
- `observerModel`: document-level only once it affects saved analysis or CVD
120-
behavior. Until then, keep it fixed at the current default and use the new
121-
registry internally to stabilize tails.
139+
behavior. Until then, keep it fixed at the current default and move that
140+
default onto reference data internally.
122141
- `chromaticityDiagram`: local UI preference if it only changes the xy/u'v'
123142
instrument view; document-level only if diagram selection becomes semantic
124143
for picking, saved annotations, or exported analysis.
125144

126145
### Sequencing with the Current Roadmap
127146

128-
1. **Tail stabilization can ship first without a schema bump.** Replacing the
129-
unstable analytical tails with table/spline data behind the current default
130-
observer is a correctness fix for existing behavior.
147+
1. **Reference-validated evaluator work can ship first without a schema bump.**
148+
Replacing or segmenting the unstable analytical evaluator behind the current
149+
default observer is a correctness fix for existing behavior. The replacement
150+
may be table-interpolated or analytical, but it must be benchmarked against
151+
reference data and preserve colorimetric outputs at range extremes rather
152+
than merely suppress visible artifacts.
131153
2. **Chromatic adaptation should precede exposed observer/profile choices.**
132154
The same shared `DerivedMatrices` path should carry white-point adaptation
133155
and observer/display matrices so CPU, GPU, picking, and panels agree.
@@ -160,29 +182,35 @@ The CVD simulation is performed by projecting RGB colors into the LMS color spac
160182
- **Impact**: Exposing user-selectable observer/diagram settings may require
161183
persistence, but only after deciding whether each setting is document semantic
162184
or local preference.
163-
- **Resolution**: Do **not** bump the schema for the tail-stability fix. If a
164-
later phase persists document-level observer choices, store them under the
185+
- **Resolution**: Do **not** bump the schema for evaluator replacement while the
186+
selected observer identity stays the same. If a later phase persists
187+
document-level observer choices, store them under the
165188
global color/observer context, not `theme`, and then follow the document
166189
persistence playbook with an explicit migration.
167190

168191
---
169192

170193
## 6. Detailed Implementation Plan
171194

172-
### Phase 1: Experimental Data & Fit Comparison
173-
1. Write a scratch script under `fe/src/lib/color/scratch/compare-fundamentals.ts` to load CVRL datasets.
174-
2. Compare the user's custom Gaussian formula from `pipeline.ts` to identify its exact source data (e.g., Stockman & Sharpe 2°).
175-
3. Evaluate the fit MSE and determine stable bounds.
176-
4. Replace only the current default evaluator if the comparison confirms a
177-
drop-in table/spline fix; this phase should not add UI or persistence.
195+
### Phase 1: Reference Data & Fit Audit
196+
1. Write a scratch script under `fe/src/lib/color/scratch/compare-fundamentals.ts` to load CVRL/CIE reference datasets.
197+
2. Compare the current Gaussian-derivative formula from `pipeline.ts` against the relevant reference data to identify its closest source model and quantify errors across the full visible range, with special attention to the low-energy tails.
198+
3. Select the reference dataset that should define the current default observer. Prefer newer physiological observer measurements where they match the intended model; document any mismatch with CIE 1931/1964 diagram geometry.
199+
4. Compare evaluator strategies:
200+
- current analytical fit over any range where it remains accurate;
201+
- shape-preserving interpolation from reference samples;
202+
- continuous analytical alternatives or segmented fits.
203+
5. Implement the default evaluator from the strategy with the best documented accuracy/behavior tradeoff. Reject interpolation or analytical methods that overshoot, go negative, oscillate, diverge, or distort spectral-locus extremes.
204+
6. Keep this phase UI-free and persistence-free: it changes the numeric evaluator for the same observer identity, not the saved document shape.
178205

179206
### Phase 2: Registry & Mathematical Foundation
180207
1. Implement `fe/src/lib/color/fundamentals.ts` containing:
181-
- Analytical spline evaluators for Stockman-Sharpe 2°/10° and Smith-Pokorny 2°.
208+
- Reference-validated evaluators for Stockman-Sharpe 2°/10° and Smith-Pokorny 2°.
182209
- Matrices for LMS $\leftrightarrow$ XYZ mapping.
183210
2. Implement `fe/src/lib/color/diagrams.ts` containing the coordinate projection math for CIE 1931 xy, CIE 1976 UCS u'v', and CIE 2006 xy.
184-
3. Keep the active runtime default identical to current behavior until CVD and
185-
panel parity are ready.
211+
3. Keep the selected default observer identity unchanged until CVD and panel
212+
parity are ready, but preserve only evaluator segments that meet the
213+
documented reference-data error and tail-behavior criteria.
186214

187215
### Phase 3: WebGL & CVD Updates
188216
1. Modify `rebuildMatrices` in `fe/src/lib/renderer/uniforms.ts` to compute `RGB2LMS` and `LMS2RGB` dynamically using the active LMS model.

_docs/pipeline-node-ui-proposal.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,9 @@ Implementation timing:
161161
- Keep the current selector visible until the global Color Context exists.
162162
- Best timing for the move is after chromatic adaptation or together with Display gamut preferences/classification. Before that, the Color Context would be mostly a renamed control with little explanatory payoff.
163163
- Do not expose observer selection before `fundamentals.ts` / `diagrams.ts`
164-
registries and matching CVD matrices exist. A tail-stability fix can remain
165-
invisible and does not need a new UI surface.
164+
registries and matching CVD matrices exist. Auditing/correcting the current
165+
evaluator against reference observer data can remain invisible and does not
166+
need a new UI surface.
166167

167168
#### Explorer Reference / Display Mapping
168169

0 commit comments

Comments
 (0)