feat(record-zstack): Hamamatsu fps not settable — report achievable rate, read-only UI#587
Open
hongquanli wants to merge 1 commit into
Open
Conversation
…ate, don't try to set Hamamatsu ORCA can't command a frame rate in CONTINUOUS mode (INTERNAL_FRAMERATE and INTERNAL_FRAMEINTERVAL are read-only, bench-verified: DCAMERR.NOTWRITABLE). It free-runs at the exposure/readout-limited max, overlapping exposure with readout. Make the UI and worker match, generalized via a camera capability so ToupTek (which CAN set via PRECISE_FRAMERATE) is unaffected. - AbstractCamera.can_set_frame_rate() (default True) + estimate_frame_rate(exposure_ms) (default sequential 1000/(exposure+strobe)). - HamamatsuCamera: can_set_frame_rate() -> False. set_frame_rate() reports the camera's AUTHORITATIVE free-run rate by reading the read-only INTERNAL_FRAMERATE (which reflects the current readout mode fast/standard/ultraquiet, bit depth, ROI and exposure), falling back to the overlap estimate only if the read fails. estimate_frame_rate() = overlap 1000/max(readout, exposure) (readout = line_interval * rows) for the widget's preview at a hypothetical exposure. Neither path writes anything (removes the NOTWRITABLE ERROR + the READOUTSPEED side-effect of the earlier approach). - Record widget: when the camera can't set fps, the fps field is read-only and shows "~ X fps", recomputed from the (still-editable) recording exposure (incl. after a YAML load). - Worker: for not-settable cameras, size/pace the recording to the achievable max instead of honoring params.fps. Tests: base/sim capability + estimate; worker sizes to achievable; widget read-only vs editable. Hamamatsu-specific test (authoritative-read vs formula-fallback + overlap math) guarded on the DCAM lib (absent off-instrument); the overlap math is also covered by the ToupTek continuous-max tests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
On the Hamamatsu ORCA the continuous-mode frame rate is not settable —
INTERNAL_FRAMERATEandINTERNAL_FRAMEINTERVALare read-only in every camera state (bench-verified:DCAMERR.NOTWRITABLE). It free-runs at the exposure/readout-limited max, overlapping exposure with readout. This makes the Record + Z-Stack UI and worker reflect that, generalized via a camera capability so it composes cleanly with the ToupTek_continuous_max_frameratework already on this branch (ToupTek can set the rate viaPRECISE_FRAMERATEand is untouched).Supersedes the earlier
INTERNAL_FRAMERATE-writing attempt (which produced aNOTWRITABLEERROR at the bench and silently forcedREADOUTSPEED=FASTEST).Changes
AbstractCamera:can_set_frame_rate()(defaultTrue) +estimate_frame_rate(exposure_ms)(default sequential1000/(exposure+strobe)).HamamatsuCamera:can_set_frame_rate() → False.set_frame_rate()reports the camera's authoritative free-run rate by reading the read-onlyINTERNAL_FRAMERATE— which reflects readout mode (fast/standard/ultraquiet), bit depth, ROI and exposure — falling back to the overlap estimate only if the read fails. No writes.estimate_frame_rate()= overlap1000/max(readout, exposure)(readout =INTERNAL_LINEINTERVAL × rows), for the widget's preview at a hypothetical exposure the camera isn't set to.params.fps.Testing
max()branches) vs editable for settable cameras.blackclean.Review
Independent review: no Critical, no Important; Minor items addressed (docstring accuracy on the capability default; refresh the read-only display after YAML load) or noted (display-only spinbox clamp at multi-second exposures). Reading
INTERNAL_FRAMERATEfor the actual rate resolves the reviewer's "ROI not reflected in the estimate" note for the worker path.Off-instrument constraint
HamamatsuCameracan't be imported/run without the DCAM library, so its methods arepy_compile+ static-review verified here and will first execute on the ORCA. Bench check: confirmset_frame_ratereturns a plausible full-frame value (~40–95 fps at short exposures) and the widget's "≈ X fps" tracks exposure.🤖 Generated with Claude Code