id3c.utils.flyscan_3idc_analysis#
Post-run analysis helpers for flyscan_3idc runs.
This module pairs each detector frame with the motor’s
interpolated position at the frame’s IOC timestamp, using the
monitor streams that flyscan_3idc.flyscan sets up via
@bpp.monitor_during_decorator. No bluesky, no ophyd, no
RunEngine — purely operates on BlueskyRun-shaped objects from
tiled / databroker.
Usage#
from tiled.client import from_profile
cat = from_profile("your_profile")["your_tree"]
run = cat[-1]
from id3c.utils.flyscan_3idc_analysis import pair_frames_to_positions
df = pair_frames_to_positions(run)
# df columns: image_number, timestamp, position
# df.index: absolute timestamp (float seconds since epoch)
df.to_csv("scan.csv")
Design notes#
IOC timestamps are the system of record for pairing (per the
flyscan_3idcstrategy doc, Phase 0.2 / Phase 0e). The primary-stream snapshots from the plan are a progress indicator; this module’s output is the high-fidelity pairing.Empirically (verified during the 2026-06-08 commissioning session against
adsimdet+gp:m1): - the m1 monitor stream’s record-order is interleaved acrossmultiple CA dispatcher segments; sorting by timestamp yields a strictly increasing position trace at constant velocity in the in-scan window.
the HDF array_counter monitor stream’s record-order is also interleaved, but sorting by timestamp yields strictly monotonic counter values (0, 1, 2, …, contiguous).
The function uses linear interpolation of motor position vs motor IOC timestamp. Linear is exact for a motor at constant velocity in the in-scan window (which is the entire reason the plan sets velocity = (p_end-p_start)/(num_frames*t_period) and taxis the motor up to scan velocity before crossing p_start).
Frames whose timestamps fall outside the motor stream’s time range are dropped (extrapolation is rejected, never silent).
Frames whose interpolated positions fall outside
[p_start, p_end]are dropped (this is “frames captured during taxi-in / coast-out” — they’re in the HDF5 file but not part of the scan).
Attributes#
Functions#
|
Pair each in-scan HDF frame with the interpolated motor position. |
Module Contents#
- id3c.utils.flyscan_3idc_analysis.pair_frames_to_positions(run) pandas.DataFrame[source]#
Pair each in-scan HDF frame with the interpolated motor position.
Reads everything from the run’s start-document metadata and the standard monitor streams set up by
flyscan_3idc.flyscan:<flymotor_name>_monitor— motor position vs IOC timestamp.<det_name>_hdf1_array_counter_monitor— HDFarray_countervs IOC timestamp.p_start/p_endfromrun.metadata["start"].
Frames captured outside
[p_start, p_end]are dropped. Frames whose IOC timestamps fall outside the motor stream’s time range are dropped (extrapolation never happens silently).- Parameters:
run (BlueskyRun) – Tiled / databroker run object. Must have
.metadata["start"]with the keysp_start,p_end,flymotor_name,det_name, and must expose monitor streams named per the convention above.- Returns:
Columns:
image_number(int64, the HDF array_counter value at frame capture),timestamp(float, IOC time of capture),position(float, motor position in engineering units, linearly interpolated). Indexed bytimestampascending.- Return type:
pandas.DataFrame
- Raises:
KeyError – Required metadata key or monitor stream is missing from the run.
ValueError – Motor stream has fewer than 2 samples (cannot interpolate).