Skip to content

Enable Synthetic DAQ Support for Real Camera Devices - #1233

Merged
kevin-m-dean merged 13 commits into
TheDeanLab:developfrom
annie-xd-wang:synthetic-DAQ-with-real-Camera-devices
Sep 8, 2026
Merged

kevin-m-dean merged 13 commits into
TheDeanLab:developfrom
annie-xd-wang:synthetic-DAQ-with-real-Camera-devices

Conversation

@annie-xd-wang

Copy link
Copy Markdown
Collaborator

No description provided.

Copy link
Copy Markdown
Collaborator

Implemented the inactive-camera guard in d6c35604b.

Why this guard is needed

SyntheticDAQ.wait_acquisition_done() calls generate_new_frame() for every camera registered with the synthetic DAQ on each acquisition step. Camera registration persists at the microscope level, so a camera can remain registered even when it is not currently acquiring.

Before this change, the Hamamatsu implementation fired a DCAM software trigger whenever trigger_source == "Software", without checking is_acquiring. That meant an inactive Hamamatsu camera could still be exposed and read out even though Navigate was not accepting its frames; those frames were subsequently discarded. In addition to unnecessary exposure/readout, sending triggers to an inactive device creates avoidable camera-state and acquisition-timing risk.

The new device-level guard returns immediately when is_acquiring is false. This is intentionally placed in HamamatsuBase.generate_new_frame() so the method is safe regardless of which caller requests a frame. Active Hamamatsu cameras in Software mode continue to receive exactly one trigger.

Regression coverage verifies both sides of the contract:

  • inactive camera: zero calls to fire_software_trigger()
  • active camera: one call to fire_software_trigger()

Follow-up: formalize software-trigger capability

This PR also exposes a broader inconsistency: camera backends do not currently have a uniform, formalized Software trigger mode. Some cameras advertise only External/Internal trigger sources, while microscope setup currently forces trigger_source = "Software" whenever a SyntheticDAQ is used. That can place a camera into a mode it does not advertise or implement.

[P2] Only force Software mode for cameras that support it.

As a follow-up, the SyntheticDAQ setup should gate that configuration change on each camera's supported_trigger_sources. Longer term, software triggering should be a formal camera capability/interface—covering both mode selection and generate_new_frame() behavior—so the DAQ does not depend on backend-specific conventions.

Validation

  • Hamamatsu regression plus nearby SyntheticDAQ/microscope tests: 19 passed
  • Black, Ruff, and git diff --check: passed
  • The broader suite reached 1,751 passed with two unrelated baseline/environment failures, both reproduced without this guard (missing Java for OME XML validation and existing feature-record state).

@annie-xd-wang
annie-xd-wang marked this pull request as ready for review August 31, 2026 21:22
@kevin-m-dean

Copy link
Copy Markdown
Collaborator

@annie-xd-wang, I know you have tested all of these camera systems, so your hardware results carry more weight here. An AI-assisted review flagged three points, and I wanted to see whether you think any of them are worth considering:

  1. With the synthetic DAQ, generate_new_frame() sends the software trigger and returns immediately. The acquisition path can then turn off the laser or request the next frame before the camera has completed its exposure. Does the behavior you observed on the cameras indicate that an explicit wait or readiness check is needed here?
  2. Microscope initialization with a SyntheticDAQ writes trigger_source = "Software" into the experiment configuration. Because experiment settings are saved on exit, that value can remain when the same experiment is next opened with a hardware DAQ. Would it be safer to keep this as a runtime override so the saved External setting is preserved?
  3. MU196XRCamera.set_trigger_mode() now always selects XI_GPI_PORT2, even when input_trigger_port specifies another port. Is port 2 mandatory for the supported MU196 setup, or should the configured port still be honored with port 2 as the default?

These may be false positives in light of your real-camera testing; I mainly wanted to put them in front of you before we merge.

@annie-xd-wang

Copy link
Copy Markdown
Collaborator Author

Issue 2: Fixed
We can ignore issue 1 and 3.

@kevin-m-dean
kevin-m-dean self-requested a review September 8, 2026 19:01
@kevin-m-dean
kevin-m-dean merged commit 215e814 into TheDeanLab:develop Sep 8, 2026
1 check passed
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.

2 participants