Part of #50 (device-layer refactor). Owner: @ceej640. Can start in parallel with
#79 / #80 — it doubles as the acceptance test for the BaseDeviceLayer seam.
Goal
Add a declarative hardware profile for a second microscope (AO-adiSPIM) that runs
offline / dummy, with critical motion disabled and read-only/no-op placeholders for
AO-specific devices. This is the concrete second data point that tells us whether the
device-layer abstraction is generalizable, without touching live hardware.
Why AO-adiSPIM is the right test case
It shares the diSPIM hardware family (scanner/camera/stage overlap) but breaks several
hidden assumptions baked into the current diSPIM plugin (per @ceej640's analysis in #50):
- Asymmetric views ~56.7° / 33.3° (vs. diSPIM 45°/45°) → different per-view
effective magnification, pixel size, and FOV.
- Frame layout is untyped — "side-by-side" halves aren't declared as physical View
A/B vs. spectral-splitter channels; equal-width halves ≠ equal physical scale.
- Stage semantics differ —
ZStage:V:37 is currently mapped to DiSPIMFDrive (a
moving-head F-drive), but both scopes use a fixed-head FTP stage, and the safe-height
envelope depends on physical mount height, which differs per system.
- No rotation optics (C60-CUBE-135) or image splitter, unlike the Gently diSPIM.
Profile should declare explicitly (not inherit)
Device identity, physical role, units, per-axis safety envelope, firmware-vs-software
limit source, homing/zero convention, view angle/geometry, per-view pixel size + FOV,
camera orientation/affine, frame layout, tile identity, channel identity, and
whether each motion/actuation path is enabled or read-only.
First pass (safe subset)
Define only the safe/common pieces — cameras, scanner, stage readout, piezos if clearly
mapped — plus read-only/no-op placeholders for AO devices. Leave critical motion disabled
until V/W axis mapping, physical limits, and view transforms are explicit and validated.
Open question
Where does the profile schema live — promoted into core/harness so both plugins
import it, or started inside the AO-adiSPIM plugin and promoted once it stabilizes?
Leaning toward the latter to avoid freezing the schema too early.
Acceptance
Boots against BaseDeviceLayer (#80) and streams device state without importing any
diSPIM-specific code.
Part of #50 (device-layer refactor). Owner: @ceej640. Can start in parallel with
#79 / #80 — it doubles as the acceptance test for the
BaseDeviceLayerseam.Goal
Add a declarative hardware profile for a second microscope (AO-adiSPIM) that runs
offline / dummy, with critical motion disabled and read-only/no-op placeholders for
AO-specific devices. This is the concrete second data point that tells us whether the
device-layer abstraction is generalizable, without touching live hardware.
Why AO-adiSPIM is the right test case
It shares the diSPIM hardware family (scanner/camera/stage overlap) but breaks several
hidden assumptions baked into the current diSPIM plugin (per @ceej640's analysis in #50):
effective magnification, pixel size, and FOV.
A/B vs. spectral-splitter channels; equal-width halves ≠ equal physical scale.
ZStage:V:37is currently mapped toDiSPIMFDrive(amoving-head F-drive), but both scopes use a fixed-head FTP stage, and the safe-height
envelope depends on physical mount height, which differs per system.
Profile should declare explicitly (not inherit)
Device identity, physical role, units, per-axis safety envelope, firmware-vs-software
limit source, homing/zero convention, view angle/geometry, per-view pixel size + FOV,
camera orientation/affine, frame layout, tile identity, channel identity, and
whether each motion/actuation path is enabled or read-only.
First pass (safe subset)
Define only the safe/common pieces — cameras, scanner, stage readout, piezos if clearly
mapped — plus read-only/no-op placeholders for AO devices. Leave critical motion disabled
until V/W axis mapping, physical limits, and view transforms are explicit and validated.
Open question
Where does the profile schema live — promoted into
core/harnessso both pluginsimport it, or started inside the AO-adiSPIM plugin and promoted once it stabilizes?
Leaning toward the latter to avoid freezing the schema too early.
Acceptance
Boots against
BaseDeviceLayer(#80) and streams device state without importing anydiSPIM-specific code.