…RNALFRAMERATE
Add HamamatsuCamera.set_frame_rate() (was inheriting the AbstractCamera no-op)
so Record+Z-Stack recording caps the ORCA's internal free-run rate instead of
free-running at the exposure/readout-limited max and downsampling in software.
- Forces fast readout (DCAMPROP.READOUTSPEED.FASTEST) before reading the
INTERNALFRAMERATE ceiling, so high (>30 fps) targets aren't pinned to the
slow/low-noise mode's limit.
- Clamps the request to the property's valid range, sets it, and returns the
achieved rate (base contract). Any failure falls back to the exposure-limited
max (== prior behavior), so recording stays correct even if the props are
unsupported.
Untested on hardware locally (no DCAM lib on the dev Mac); verified py_compile +
black only. Hardware verification pending on ORCA-Fusion BT (C15440-20UP).
Known follow-up: readout speed is left in fast mode after recording (not
restored); make it configurable / restore for low-noise low-fps recording.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Adds
HamamatsuCamera.set_frame_rate()so the Record + Z-Stack feature (#564) caps the ORCA's internal free-run rate on Hamamatsu instead of relying only on software downsampling.Before this,
HamamatsuCamerainherited theAbstractCamera.set_frame_rateno-op: recording ran the sensor inCONTINUOUS(internal-trigger) mode at its exposure/readout-limited maximum and theRecordingRouterdownsampled to the target fps in software. That is correct (excess frames are cleanly rejected, not counted as drops), but at high fps / full resolution the read thread must process ~10.6 MB/frame it then discards — risking read-thread saturation and, in the worst case, under-delivery (blank trailing planes).What it does
set_frame_rate(fps)to set DCAMINTERNALFRAMERATE, matching the ToupTekPRECISE_FRAMERATEcontract: clamp the request to the property's valid range, set it, return the achieved rate; on any failure fall back to1000/get_total_frame_time()(== prior behavior), so recording stays correct even where the properties are unsupported.DCAMPROP.READOUTSPEED.FASTEST) — high frame rates require it, and the sensor's default may be the low-noise (slow) mode whoseINTERNALFRAMERATEceiling is far below the target. Setting it first also raises thevaluemaxwe then read, so the clamp isn't pinned to the slow-mode limit.Stacking
Stacked on
feat/record-zstack-acquisition(#564), not master, because theAbstractCamera.set_frame_ratebase method this overrides only exists on #564's branch. Rebase onto master once #564 merges (same as #579).Verification status
py_compile+blackclean.dcamapi4.pydlopen'slibdcamapi.soat import, absent on macOS, and simulation uses a different camera class. This code has never executed.set_frame_rate(...) set INTERNALFRAMERATE -> X fps(X ≥ target = good).zattrs:acquisition_complete: true,captured_frames == expected_frames,dropped_frames: 0Known follow-up (out of scope here)
Readout speed is left in fast mode after a recording (not restored). Acceptable for throughput-oriented recording; a follow-up should make readout speed configurable / restore it for low-noise low-fps recording.
🤖 Generated with Claude Code