126 lines
4.5 KiB
Markdown
126 lines
4.5 KiB
Markdown
# 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.
|
|
|