Skip to content

Fix viewer grab loop: hardware_averaging and live_mode_available are independent - #1422

Merged
seb5g merged 1 commit into
5.3.xfrom
fix/viewer-live-averaging
Oct 27, 2026
Merged

seb5g merged 1 commit into
5.3.xfrom
fix/viewer-live-averaging

Conversation

@seb5g

@seb5g seb5g commented Oct 26, 2026

Copy link
Copy Markdown
Contributor

Before: with a plugin having both live_mode_available = True and hardware_averaging = True, the grab loop of the viewer never ended. plugin.grab_data was called again after every received data, each call starting another acquisition loop (stack overflow within seconds at 100 FPS, as reported by @rgeneaux in PyMoDAQ/pymodaq_plugins_utils#10). With software averaging and Naverage > 1, several streams were started, and grab_stopped was emitted while the plugin still streamed.

After: the two attributes are independent. A plugin that streams (live_mode_available, live grab) is called once and emits until it is stopped; grab_stopped is emitted then. hardware_averaging only tells who averages: the plugin (each emitted data is already an average) or the viewer in data_ready, also while streaming. Single grabs and plugins that do not stream are unchanged.

What changes: DAQ_Viewer_hardware.grab_data leaves the loop right after the first call for a streaming plugin (the old exit condition is removed), STOP_GRAB emits grab_stopped in that case, and the contract of both attributes is written in DAQ_Viewer_base.

How: new viewer_grab_loop_test.py drives a DetectorWorker with a stub plugin counting the calls to grab_data, for streaming or not, hardware averaging or not, live or single. Four of its tests fail on the previous code (both flags True, and grab_stopped too early). The existing viewer and plugin error tests pass. Tested with stubs only, no real camera. It still has to be checked with a real streaming camera plugin (CameraBase of pymodaq_plugins_utils with hardware_averaging = True).

Closes #1421. Ports to dev and 5.2.x follow.


Generated by Claude Code

…e_averaging

With live_mode_available and hardware_averaging both True, the loop of
DAQ_Viewer_hardware.grab_data never ended and called plugin.grab_data again
after every received data, each call starting another acquisition loop.

The two attributes are now independent: a plugin that streams is called once,
the grab ends (grab_stopped) when it is stopped, and the software averaging is
still done in data_ready when the plugin does not average itself.

Closes #1421

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tdiso1u1ZhikSutj2Qs5Cg

seb5g commented Oct 26, 2026

Copy link
Copy Markdown
Contributor Author

CI note: the red job is tests (ubuntu-latest, 3.12, pyside6). It aborted with free(): invalid size while tearing down a fixture of tests/extensions/closing_behaviour_test.py (_flush_deleted_widgets in extension_testing.py), the PySide6 crash on deleted widgets that is already known, in code this PR does not touch. All 13 tests added here and the existing viewer tests passed before the abort, and the other five jobs are green. 5.3.x itself was green after #1356. I re-run the failed job once; if it fails again at another place I look at it again.


Generated by Claude Code

@seb5g
seb5g merged commit 73e3cb5 into 5.3.x Oct 27, 2026
14 of 15 checks passed
@seb5g
seb5g deleted the fix/viewer-live-averaging branch October 27, 2026 09:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

DAQ_Viewer: hardware_averaging and live_mode_available interfere in the grab loop

2 participants