focus: a low number can mean nothing to focus on, and says which - #38
Conversation
Second round of feedback from the same calibration: "теперь классическая проблема - на 9 квадрате не нашлось резких объектов и ему маленькую цифру дали". He is right, and it is the classic one. A blank wall, a patch of sky, a smooth painted door all report a small focus value wherever the lens is, because these statistics measure detail and there is none there to measure. Shown as a bare small number it reads as "this part of the picture is soft", and the operator goes chasing focus that was never the problem. A zone with something in it RESPONDS when the lens moves; a zone without one does not. That is the whole test, and peakHold already had half of it -- it tracked each zone's best, so it now tracks the low as well and swing becomes a live statistic, accumulated as the barrel turns rather than needing a sweep. Nothing is claimed until the frame AS A WHOLE has moved. "We have not looked yet" and "there is nothing there" are different answers and only one of them is the operator's problem, so before that every block is unknown. An empty block keeps its number -- it is what the camera reported -- but dimmed and captioned, so it stops carrying the weight of a verdict. It can never be named the sharpest either: that points the operator at the one part of the frame which can never answer. Unless nothing has detail at all, when the plain maximum stands rather than naming no block on a frame that may simply not have been swept yet. sweepZones now reports WHY a zone had no opinion -- responded, flat, pinned, unmeasured -- rather than dropping all four into the same null. `flat` is this same finding taken from the one measurement where the lens definitely moved. Two of my own mistakes, both caught by the tests: zoneDetail was handed the holder rather than the push result, so it saw no record at all; and coarsen read a missing entry as KNOWN, which between them captioned all nine blocks "nothing to focus on" on a frame nobody had swept. Only the two real answers count as knowing now.
PR Summary by QodoDistinguish detail-free zones from soft focus
AI Description
Diagram
High-Level Assessment
Files changed (8)
|
Code Review by Qodo
1.
|
Three from review, all real, and two of them one mistake: I conflated a zero reading with no reading, in code whose own comment already says they are different. A lit zone reading zero at every lens position is the emptiest zone there is. zoneDetail skipped it for hi <= 0 and left it unknown, so the block most in need of "nothing to focus on" was the one block that never got it; and sweepZones called it unmeasured, telling the operator the zone could not be read when it had been read and found empty. null stays unknown -- that one really is never measured. Zero is 'none' and 'flat'. The accumulators cannot go negative, so hi === 0 means lo === 0 and there is no swing to divide for. peakHold kept its record across a reshape. Same class as the sweep bug fixed last round, in the live path this time: two grids of the same size and different shape put the same index somewhere else in the picture, so the held per-zone record describes the wrong zones. Worse, the mismatch branch cleared only those arrays and never bestOverall/lowOverall -- which are the gate deciding whether the lens has moved at all, so the gate went on answering from a range measured on a camera that no longer existed. The record is now keyed on the shape and all four are cleared together.
|
All three were real and are fixed in 6ec3423. Two of them are one mistake on my part: I conflated a zero reading with no reading, in code whose own comment already says they are different. 2 — Zero-value blocks stay unexplained. Correct. A lit zone reading zero at every lens position is the emptiest zone there is, and 3 — Sweeps mislabel measured zero zones. Same mistake in 1 — Focus labels move to the wrong blocks. Correct, and it is the same class as the sweep shape bug fixed last round, in the live path this time. Two grids of the same size and different shape put the same index somewhere else in the picture, so the held per-zone record describes the wrong zones. Your evidence caught something worse than the headline, and thank you for it: the mismatch branch cleared only TestsFive assertions added. All four mutations discriminate:
The reshape test first asserts the lens has visibly moved on the old shape, so it cannot pass by everything being
|
Second round of feedback from the same calibration session:
He is right, and it is the classic one. A blank wall, a patch of sky, a smooth painted door all report a small focus value wherever the lens is, because these statistics measure detail and there is none there to measure. Shown as a bare small number it reads as "this part of the picture is soft", and the operator goes chasing focus that was never the problem.
The test
A zone with something in it responds when the lens moves; a zone without one does not. That is the whole test — and
peakHoldalready had half of it. It tracked each zone's best, so it now tracks the low as well, and swing becomes a live statistic accumulated as the barrel turns rather than something needing a sweep.Nothing is claimed until the frame as a whole has moved. "We have not looked yet" and "there is nothing there" are different answers and only one of them is the operator's problem, so before that every block is
unknown.What it shows
An empty block keeps its number — it is what the camera reported — but dimmed and captioned "nothing to focus on", so it stops carrying the weight of a verdict.
It can never be named the sharpest, either: that points the operator at the one part of the frame which can never answer. Unless nothing has detail at all, in which case the plain maximum stands rather than naming no block on a frame that may simply not have been swept yet.
One textured corner is enough, so a block is only called empty when every zone in it that could be measured agrees.
And from the sweep
sweepZonesnow reports why a zone had no opinion —responded/flat/pinned/unmeasured— rather than dropping all four into the samenull.flatis this same finding taken from the one measurement where the lens definitely moved.Two of my own mistakes, both caught by the tests
zoneDetailwas handed the holder rather than the push result, so it saw no record at all.coarsenread a missing entry as known.Between them those captioned all nine blocks "nothing to focus on" on a frame nobody had swept. Only the two real answers count as knowing now, and there are tests for a short array and for no array at all.
Tests
Nine assertions in
tools/smoke.mjs, five intests/ui-check.html. Every guard mutation-tested:node tools/smoke.mjsandnode tools/ui-check.mjsboth pass.