mgth/LittleBigMouse · error · CalibrationMeasurementException
The probe returned an invalid Delta E value.
Error message
The probe returned an invalid Delta E value.
What it means
WhitePointOptimizer.MeasureAtGainsAsync applies a gain setting, waits the settle delay, and reads the probe measurement. If measurement.DeltaE is not finite (NaN or Infinity), the value is useless for optimization, so the library throws CalibrationMeasurementException instead of caching or optimizing against garbage data.
Solutions
- Retry the measurement at the same gains after re-seating/stabilizing the probe on the panel
- Verify the probe is connected, calibrated, and its driver/firmware reports valid readings outside this library
- Increase settleDelay so the display and probe reach steady state before MeasureAsync
- Catch CalibrationMeasurementException around optimization and abort/restart the calibration run
Example fix
// before
var result = await optimizer.OptimizeAsync(...); // throws on NaN DeltaE
// after
try { var result = await optimizer.OptimizeAsync(...); }
catch (CalibrationMeasurementException ex)
{
logger.LogWarning(ex, "Probe returned invalid Delta E; recheck probe placement and retry.");
} Defensive patterns
Strategy: try-catch
Validate before calling
var m = await hardware.MeasureAsync(ct);
if (!double.IsFinite(m.DeltaE))
throw new CalibrationMeasurementException("Probe returned invalid Delta E."); Type guard
static bool IsValidMeasurement(ProbeMeasurement m) => double.IsFinite(m.DeltaE);
Try / catch
try
{
await optimizer.OptimizeAsync(...);
}
catch (CalibrationMeasurementException ex)
{
// abort calibration, prompt probe recheck, offer retry
} Prevention
- Seat the probe firmly and keep it undisturbed during settle delays
- Increase settleDelay for slow-refreshing displays
- Verify probe calibration/driver health before starting optimization
- Retry individual measurements before failing the whole run
When it happens
Trigger: Calling MeasureAtGainsAsync (directly, or via TuneChannelAsync / the baseline and measured passes) when hardware.MeasureAsync returns a DeltaE of NaN or Infinity — e.g. the colorimeter lost its calibration, returned a failed reading, or measured in an invalid state.
Common situations: Probe unclipped or moved during settling; ambient light or a black screen producing a division-by-zero in the meter's firmware; a colorimeter driver returning sentinel values; USB hiccup producing an empty reading.
Related errors
AI-assisted analysis of mgth/LittleBigMouse@7a42f01d47 (2026-09-16).
Data as JSON: /api/errors/731455b304702642.
Report an issue: GitHub.
Appendix: source
Thrown at LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp/Calibration/WhitePointOptimizer.cs:140
return new(gains, deltaE, gains != original, reads);
}
static async Task<CachedMeasurement> MeasureAtGainsAsync(
ICalibrationHardware hardware,
CalibrationRgb gains,
TimeSpan settleDelay,
Dictionary<CalibrationRgb, double> cache,
CancellationToken cancellationToken)
{
if (cache.TryGetValue(gains, out var cached)) return new(cached, false);
await hardware.SetGainsAsync(gains, cancellationToken).ConfigureAwait(false);
if (settleDelay > TimeSpan.Zero)
await Task.Delay(settleDelay, cancellationToken).ConfigureAwait(false);
var measurement = await hardware.MeasureAsync(cancellationToken).ConfigureAwait(false);
if (!double.IsFinite(measurement.DeltaE))
throw new CalibrationMeasurementException("The probe returned an invalid Delta E value.");
cache[gains] = measurement.DeltaE;
return new(measurement.DeltaE, true);
}
static bool CanMove(
CalibrationRgb gains,
IReadOnlyList<int> channels,
int count,
IReadOnlyList<uint> boundary,
bool down)
{
for (var i = 0; i < count; i++)
{
var value = gains.Channel(channels[i]);
if (down ? value <= boundary[i] : value >= boundary[i]) return false;
}
return true;
}View on GitHub (pinned to 7a42f01d47)