Files
superxas_bec/docs/scan_v4_migration_plan.md
T

4.5 KiB

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:

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.