A rotation run whose first pass found no lattice threw NoLatticeFound before
any canonical pass, so no image was ever reported as the canonical pass: the
live scan result and the master file's per-image arrays were empty, and the
CLI wrote nothing per image. Run() now catches it, runs one output pass over
every frame with spot finding and the per-image analysis but indexing off
(SpotFindingPass: header geometry, the run's spot finding, pre-scan mask kept;
the first pass, supercell probe, rotation finalize and merge skip a pass with
indexing off), reports it through the observer as the canonical pass, hands
the result back on the exception (NoLatticeFound::per_image) and rethrows -
the verdict and the report are unchanged. Skipped when cancelled and when Run
has no observer (the live lattice probe).
The CLI writes that result where a run that indexed nothing puts its
per-image analysis: the _process.h5 (streamed by the sink with --no-merge or
--write-process-h5, otherwise written from the end message) and the _plot.txt;
the exit status stays 1. An output pass with no sink now fills the end
message's per-image arrays (ScanResultGenerator) for that file, which it
claimed to carry but did not. The no-lattice hint no longer points at
--mode azint for the per-image analysis.
Measured offline on two 16M no-crystal controls (1800 frames): the extra pass
is 1.6 s, wall +1.2-2.3 s.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PXc1zD1yxHqaR1DGdCTHL4