Skip to content

LAB-319 / Block S: read-only SiPM controller node (bias, enable, offsets, temperature into the run log) - #266

Closed
mbreiser wants to merge 5 commits into
claude/scanimage-frames-wrapperfrom
claude/sipm-node
Closed

mbreiser wants to merge 5 commits into
claude/scanimage-frames-wrapperfrom
claude/sipm-node

Conversation

@mbreiser

@mbreiser mbreiser commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #261 (claude/scanimage-frames-wrapper), so this diff is only the SiPM commit. Retarget to main once #261 merges.

Implements LAB-319 (split out of LAB-308, ScanImage documentation for agents, Bergamo III); uses the LAB-303 connector pattern.

Why

The SiPM detector settings (bias, enable, offsets, bandwidth, temperature) are not in ScanImage or its TIFF header. This node reads them through the vendor ThorSiPM.dll and publishes them as a connector, so they land in the run log and bag next to ScanImage and the arena.

What

  • ros2-poc/nodes/thorsipm.py — ctypes driver, no ROS. Binds only FindDevices, SelectDevice, GetParam, GetParamString, GetParamInfo, TeardownDevice (signatures from the vendor GUI's own P/Invoke metadata). No write path. CLI: scan / snapshot / watch. FakeBackend simulates the controller.
  • ros2-poc/nodes/sipm_node.py, sipm_cmd.py — /sipm/cmd, /sipm/reply, /sipm/status (1 Hz), std_msgs/String JSON like the BIAS and ScanImage connectors. Commands: ping, status, get, info, scan, disconnect, reconnect. Keeps reporting (and retrying) while the vendor GUI holds the COM port.
  • bridge_node.py, mcap_convert.py, rig.py --sipm, pixi tasks (sipm-node, sipm-cmd, sipm, test-sipm) — the sipm connector is recorded and derived like the others.

Open question the rig test answers

The GUI's Params enum gives the IDs for enable, gain, offset, bandwidth, safety, saturations and serial numbers. The DLL also names PARAM_SIPM1_BIAS, …_TEMPERATURE, …_TEMPSTATUS, but their numeric IDs aren't in the enum. Block S finds them with a read-only GetParamInfo scan and writes them to config/sipm_params.json in scanimage-2026-bergamo.

Testing

  • pixi run test-sipm: 28 / 28 (driver, node, busy port, recording) on macOS.
  • Existing suites unchanged: test-frames 39 / 39, test 54 / 54.
  • Dry run of the rig command with --fake: 16 "src":"sipm" connector events in the run log, bag closed cleanly, controller released on exit.
  • Not yet run on the real controller or on Windows. Rig procedure: rig-session-sipm-block-s.md.

🤖 Generated with Claude Code

…8/LAB-303)

The SiPM detector settings (bias, enable, offsets, bandwidth, temperature) are not in
ScanImage or its TIFF header. This adds a node that reads them through the vendor
ThorSiPM.dll and publishes them as a connector, so they land in the run log and bag.

- nodes/thorsipm.py: ctypes driver, no ROS. Binds only FindDevices, SelectDevice,
  GetParam, GetParamString, GetParamInfo and TeardownDevice (signatures from the vendor
  GUI's P/Invoke metadata); no write path. CLI: scan / snapshot / watch. FakeBackend
  simulates the controller for tests.
- nodes/sipm_node.py, nodes/sipm_cmd.py: /sipm/cmd, /sipm/reply, /sipm/status (1 Hz),
  std_msgs/String JSON like the BIAS and ScanImage connectors; commands ping, status,
  get, info, scan, disconnect, reconnect. Keeps reporting (and retrying) while the
  vendor GUI holds the COM port.
- bridge_node, mcap_convert, rig (--sipm), pixi tasks (sipm-node, sipm-cmd, sipm,
  test-sipm): the sipm connector is recorded and derived like the others.
- tests/test_sipm.py: 28 checks against the simulated controller (driver, node, busy
  port, recording). The existing suites still pass (test-frames 39/39, test 54/54).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mbreiser mbreiser changed the title LAB-308 / Block S: read-only SiPM controller node (bias, enable, offsets, temperature into the run log) LAB-319 / Block S: read-only SiPM controller node (bias, enable, offsets, temperature into the run log) Oct 19, 2026
… into claude/sipm-node

# Conflicts:
#	rig/nodes/mcap_convert.py
#	rig/nodes/sipm_cmd.py
#	rig/nodes/sipm_node.py
#	rig/nodes/thorsipm.py
#	rig/tests/test_sipm.py
On the real controller the serials came back as '0' and the firmware as '5':
the DLL writes wide strings ("000027" = 30 00 30 00 ...), and buf.value stopped
at the first NUL. Decode the raw buffer as UTF-16LE and allocate 2 x size bytes
in case size counts wide characters. Now reads 000027 / 000026 and 5.4.6, as the
GUI shows. test-sipm still 28/28 on Windows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mbreiser
mbreiser force-pushed the claude/scanimage-frames-wrapper branch from a54bd8d to 1d52b0a Compare October 28, 2026 21:23
mbreiser added a commit that referenced this pull request Oct 28, 2026
…nodes layout (LAB-319, draft)

The read-only node, its command tool, the ctypes driver and the harness moved to reiserlab/rig-nodes
0.3.0 as rig_nodes.sipm_node / sipm_cmd / thorsipm (marked EXPERIMENTAL there: never run against the
controller). What stays here: the /sipm/cmd|reply|status connector in bridge_node (recorded and
relayed like BIAS and ScanImage), the converter's derivation into connector events, rig.py --sipm /
--sipm-args, the pixi tasks, and two static harness checks.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@mbreiser
mbreiser changed the base branch from claude/scanimage-frames-wrapper to main October 28, 2026 21:23
@mbreiser
mbreiser changed the base branch from main to claude/scanimage-frames-wrapper October 28, 2026 21:44
@hanmarsan

Copy link
Copy Markdown
Contributor

Closing without merging: the read-only SiPM driver, node, command tool and harness (test-sipm 25/25 there, on the real controller in Block S) now live in the private rig repository. This branch also carried #261, which is closed the same way.

What happened to this PR's work:

Michael decided on 2026-10-28 that the imaging work is private; the details are in the §3.3 amendment in docs/development/rig-software-repos-and-runners.md. The files were copied, not rewritten in history, so this branch stays readable here.

🤖 Generated with Claude Code

@hanmarsan hanmarsan closed this Oct 29, 2026
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