WIP agent step 1: update scan v4 migration plan

This commit is contained in:
2026-05-28 08:16:52 +02:00
parent dec3549301
commit e07d3ab4c0
+125
View File
@@ -0,0 +1,125 @@
# SuperXAS scan v4 migration plan
## Scope and source mapping
This migration keeps the SuperXAS scan module boundaries intact.
| Debye v4 source | SuperXAS target |
| --- | --- |
| `debye_bec/debye_bec/scans/xas_simple_scan.py` | `superxas_bec/superxas_bec/scans/mono_bragg_scans.py` |
| `debye_bec/debye_bec/scans/nidaq_continuous_scan.py` | `superxas_bec/superxas_bec/scans/nidaq_cont_scan.py` |
The migration should not merge these scans into one file. `mono_bragg_scans.py`
remains the SuperXAS home for `xas_simple_scan` and `xas_advanced_scan`.
## Step 2: migrate `mono_bragg_scans.py`
Refactor `XASSimpleScan` and `XASAdvancedScan` from the old
`AsyncFlyScanBase` generator/stub API to the v4 `ScanBase` API used in Debye:
- inherit from `ScanBase`
- set `scan_type = ScanType.HARDWARE_TRIGGERED`
- use `@scan_hook` lifecycle methods:
- `prepare_scan`
- `open_scan`
- `stage`
- `pre_scan`
- `scan_core`
- `at_each_point`
- `post_scan`
- `unstage`
- `close_scan`
- `on_exception`
- use `self.update_scan_info(...)` for scan metadata and additional scan
parameters
- set NIDAQ readout priority through
`self.actions.set_device_readout_priority([self.daq], priority="async")`
- read monitored devices through `self.actions.read_monitored_devices()`
- kick off and complete the mono bragg motor through `self.actions.kickoff(...)`
and `self.actions.complete(..., wait=False)`
### SuperXAS-specific gonio pre-positioning
The old SuperXAS scan stages `mo1_gonio` before the mono bragg oscillation by:
1. converting start and stop energies to bragg angles
2. averaging both angles
3. moving `mo1_gonio` to that midpoint
This behavior should be preserved in the v4 scan, but migrated away from
`yield from self.stubs.send_rpc_and_wait(...)`.
Use the v4 device container and actions API instead:
```python
self.mo1_bragg = self.dev["mo1_bragg"]
self.mo1_gonio = self.dev["mo1_gonio"]
pos_start = self.mo1_bragg.convert_angle_energy(mode="EnergyToAngle", inp=self.start)
pos_end = self.mo1_bragg.convert_angle_energy(mode="EnergyToAngle", inp=self.stop)
gonio_position = (pos_start + pos_end) / 2
self.actions.set(self.mo1_gonio, gonio_position, wait=False).wait(timeout=30)
```
This pre-positioning should happen before `self.actions.stage_all_devices()`.
The default devices should be resolved from the v4 device container when they
are not passed explicitly:
- `motor`: `self.dev["mo1_bragg"]`
- `daq`: `self.dev["nidaq"]`
- `gonio`: `self.dev["mo1_gonio"]`
`XASAdvancedScan` should continue to extend the simple scan and only add spline
metadata (`p_kink`, `e_kink`) through `update_scan_info`.
## Step 3: migrate `nidaq_cont_scan.py`
Refactor `NIDAQContinuousScan` from `AsyncFlyScanBase` to v4 `ScanBase`,
following Debye's `NidaqContinuousScan`:
- keep the scan name `nidaq_continuous_scan`
- resolve the default DAQ as `self.dev["nidaq"]`
- persist `scan_duration` and `compression` with `update_scan_info`
- set DAQ async readout priority
- add device progress scan report instructions for the DAQ
- run baseline readout asynchronously in `prepare_scan`
- kick off DAQ with `wait=False`, wait up to 5 seconds for kickoff, then
`complete(..., wait=False)`
- poll monitored devices until the DAQ completion status is done
- close the scan only after the baseline status has completed
- call `self.actions.check_for_unchecked_statuses()` during close
## Step 4: migrate scan tests
Add SuperXAS tests equivalent to the Debye v4 scan tests:
- `tests/tests_scans/test_mono_bragg_scans_v4.py`
- `tests/tests_scans/test_nidaq_continuous_scan_v4.py`
- `tests/tests_scans/conftest.py`, if SuperXAS needs local v4 fixtures and
mock devices
The scan tests should verify:
- default v4 hook behavior
- scan metadata and readout priority
- mono bragg kickoff/completion loop
- NIDAQ kickoff/completion loop
- `post_scan` completion behavior
- advanced scan spline metadata
- SuperXAS gonio pre-positioning via `self.actions.set(...).wait(timeout=30)`
## Later device migration analysis
After the scan migration and tests are agreed and committed, analyze the
SuperXAS devices against the Debye equivalents:
- `superxas_bec/superxas_bec/devices/nidaq`
- `superxas_bec/superxas_bec/devices/mo1_bragg`
Special attention should be paid to Debye's migration helper
`devices/utils/utils.py::fetch_scan_info`, because it bridges old and new scan
metadata during the migration phase. The device migration plan should describe
where SuperXAS still reads old `scan_info.msg` or scan parameter shapes and how
to move those reads to the v4-compatible helper.