Feat/aerotech stages #351

Merged
holler merged 53 commits from feat/aerotech-stages into main 2026-11-03 11:44:23 +01:00
Member
No description provided.
holler added 51 commits 2026-11-03 11:34:58 +01:00
Npaq/A3200 via the ASCII command interface on the A3200 Windows PC:
enable, home (HOMEASYNC), MOVEABS, abort, fault ack, ~STATUS readback.
Simulated controller (sim_a3200), device configs for hardware and
simulation, tests. Commissioning checklist in devices/aerotech/README.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDyJxbBLmjZCEPUo5FM
- A3200Motor: arm_line_trigger/disarm_line_trigger (PSO window on the fast
  axis drives DDG1 EXT), acceleration (RAMP RATE before each move),
  encoder_channel
- A3200PositionCapture: Npaq DATAACQ latches the encoder counters on each
  detector trigger (UINT1), read back per line via ARRAY READ and published
  as async data; offset calibrated with a software PSO fire
- aerotech_cont_grid: cont_grid geometry, line start triggered by position
  instead of a software sleep
- simulator support for RAMP, $global, UNITSTOCOUNTS, PSO, DATAACQ, ARRAY READ
- configs, tests, README with wiring and commissioning checklist

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDyJxbBLmjZCEPUo5FM
- GalilRIOBurst (galil_rio_ddg.py): Galil RIO-47120 running
  RioDDG/rio_ddg.dmc (OMNY Galil repo) as line burst generator: burst mode
  switching, arm_burst, burst status, wait with pulse count check
- aerotech_cont_grid: trigger_source="ddg" (beamline) | "rio" (test setup
  without DDG/MCS)
- simulated RIO triggered by the PSO window of the simulated A3200
- configs: sastt_aerotech_test.yaml (A3200 + RIO), RIO in the simulated config
- tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDyJxbBLmjZCEPUo5FM
revert(aerotech): remove the RIO burst box trigger source
CI for csaxs_bec / test (push) Successful in 3m22s
669a7ea02b
This reverts commit bf77d6f6fe.

The RIO timing (1 ms steps, ~50 Hz opto outputs) has too much jitter to judge
whether the position sampling works, so the test setup will not use it. The
DMC program stays in the OMNY Galil repository (RioDDG).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDyJxbBLmjZCEPUo5FM
From 153722-A-1-1.prma: A3200 PC pc14643.psi.ch, axis indices X 0, Z 1, Y 2, U 3
(UU gantry slave, ZZ encoder input used by Z), limits, default speeds and ramp rates.

PSO input and DATAACQ source are now configured separately, they have different
numberings on the Npaq: motor pso_input (0-5 local counter, 6-8 MXR emulated
quadrature) + pso_counts_divider (EmulatedQuadratureDivider), capture channels are
DATAACQ sources 0-11 (6-11 = MXR channel 0-5). GlobalDoubles is 255 on SAXS-TT, so
the scratch variable moves to $global[254].

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDyJxbBLmjZCEPUo5FM
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDyJxbBLmjZCEPUo5FM
Device PandaLineTrigger (control port only): on the first line trigger edge (TTLIN3 or the
software trigger BITS.A) after arm_line(), PULSE3 -> TTLOUT2 sends a shutter pulse and
PULSE4 -> TTLOUT3 n detector pulses; COUNTER8 counts them, SRGATE1 is a one-shot arm gate.
PULSE parameters are written only when they change: on PandA FPGA 4.1 an ENABLE edge or a
parameter write often replays the previous train without a trigger.

Design SASTT_line_trigger saved on omny-panda, copy in layouts/sastt_line_trigger.ini.
Config sastt_aerotech_panda.yaml = sastt_aerotech.yaml + pandatrig.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDyJxbBLmjZCEPUo5FM
configure_line() once, arm() once, then every line trigger edge (TTLIN3 or software)
starts a line; a scan no longer re-arms per line. LUT7 accepts an edge only while armed
and while no line is running (PULSE3/PULSE4 low), so edges during a line are ignored like
on the DDG and never reach the PULSE blocks (a dropped trigger puts the FPGA 4.1 PULSE
block into the replay state). COUNTER6/7 count raw edges and accepted lines,
wait_lines_done() checks lines, gates and ignored edges. arm(one_shot=True) keeps the
single-line mode. Design SASTT_line_trigger updated on omny-panda.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDyJxbBLmjZCEPUo5FM
fix(aerotech): move completes on the controller's In Position status
CI for csaxs_bec / test (push) Successful in 3m23s
1222198a1b
First moves on the SAXS-TT hardware (X, Z, Y, +-0.5 mm, 2026-10-28): the move was
evaluated when the motion profile ended (MoveDone), X was still settling (1.2 um off) and
the move failed. After MoveDone, move() now waits for DriveStatus In Position
(InPositionDistance / InPositionTime, timeout in_position_timeout = 2 s) before comparing
with the target. axis_status() also reports in_position and encoder_clipping.
Tolerances per axis in the configs: X 1 um, Z/Y 5 um (InPositionDistance 5 um).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDyJxbBLmjZCEPUo5FM
feat(aerotech): snake scan with one PSO window per scan, arm once
CI for csaxs_bec / test (push) Successful in 3m35s
f137517e62
aerotech_cont_grid:
- snake=True (default): alternating line direction. One PSO window per scan,
  [fast_start - v*delay, exposure_end + v*delay], armed once in pre_scan; its output rises
  on entering the window, i.e. at the low edge forward and the high edge backward.
  snake=False switches the PSO off during the flyback.
- trigger_source "ddg" (beamline), "panda" (PandA configured and armed once, every line
  checked) or None (no trigger hardware); trigger_edge for DDG1, default falling (active
  low open collector / differential PSO output).
- settle_time (default 0.15 s) for the run-up at constant speed, measured on the hardware
  2026-10-28; capture_positions defaults to False until the sampling is commissioned.
- the fast axis does not wait for In Position at the turnarounds (wait_in_position signal
  of A3200Motor, off during the scan); restore steps are all tried.
PandaLineTrigger: trigger_edge config, "falling" inverts TTLIN3.

Hardware test of the scan sequence (trigger_source=None, 1x1 mm, 11 lines, X 1 mm/s):
15.3 s instead of 23.1 s; PSO window switched on at X=0.25 forward and X=0.76 backward.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDyJxbBLmjZCEPUo5FM
scan_type HARDWARE_TRIGGERED: the MCS card and the detectors are armed once at stage for
all lines x frames (existing hardware_triggered mode of mcs_card_csaxs / ddg_1) instead of
per line; per line the scan only moves the axes. With trigger_source="ddg" each line is
still checked: the MCS must have reached the line's last channel, so a missing line
trigger aborts after the first line.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDyJxbBLmjZCEPUo5FM
refactor(aerotech): aerotech_cont_grid always runs as a snake
CI for csaxs_bec / test (push) Successful in 3m27s
40c8d90072
Remove the snake argument and the raster path (flyback with PSO disarm/re-arm);
snake is the only mode used.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDyJxbBLmjZCEPUo5FM
Integer YAML map keys made the DeviceConfigMessage undecodable on SciHub
(msgpack strict_map_key), so update_session_with_file hung until timeout.
A3200PositionCapture already converts the keys with int().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
aerox settles to 10-30 nm within 0.5 s, but the controller's InPositionDistance
for X is 10 nm, so In Position took several seconds or flickered and every move
logged "not in position 2.0 s after the end of the move". The move now waits
until |PositionError| is within the axis tolerance.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
docs(aerotech): beamline examples in the aerotech_cont_grid docstring
CI for csaxs_bec / test (push) Successful in 3m23s
2944da5609
Largest (3.5 x 3.0 mm) and smallest (0.8 x 1.2 mm) field of view of the last
beamtime, each as overview, quick overview and high resolution scan.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
- A3200Motor.max_scan_velocity (default: velocity) limits the scan velocity of
  aerotech_cont_grid; the move velocity is restored after the scan, also after
  an aborted scan
- run-up / run-out: 2x ramp distance + v * settle_time (was 1.2x ramp)
- the full line range including run-up / run-out and the step axis range are
  checked against the soft limits in prepare_scan
- aerox: acceleration 500 mm/s^2, max_scan_velocity 50 mm/s, moves stay 5 mm/s

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
The PULSE blocks replay a full train ~0.3-0.6 s after a parameter write, without a
trigger. configure_line returned after 50 ms, so the train ran into the first line and
blocked its trigger (line counter 0). Now both PULSE outputs must stay low for
PARAM_QUIET_TIME (1 s); only on a parameter change, i.e. once per scan.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDyJxbBLmjZCEPUo5FM
With one closed window per scan the window exit coincided with the end of the
exposures; encoder noise at the exit edge gave extra trigger edges after the train
(2 in 11 lines on the PandA, one started an extra line). Now the window is open on the
far side of the line and only its range is switched before each line (PSOWINDOW RANGE,
no reload, so the position reference of the arm stays). Hardware test: 2 x 11 lines,
22 edges, 22 lines, 2222 gates, 0 dropped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDyJxbBLmjZCEPUo5FM
The message now says whether the scan range itself is outside the limits or
only the extra run-up travel for acceleration and settling, by how much, and
what to do about it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
docs(aerotech): README run-up formula matches the 2x ramp margin
CI for csaxs_bec / test (push) Successful in 3m25s
e4f281249b
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
config(aerotech): aerox acceleration 1000 mm/s^2
CI for csaxs_bec / test (push) Successful in 3m24s
db77f0df81
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
fix(panda): edges during a running line are logged, not a scan error
CI for csaxs_bec / test (push) Successful in 3m27s
77d08df54c
At 2 mm/s an extra edge at the PSO window entry arrived during the running line
(small field of view, line 4); it was ignored as designed, like on the DDG, but
wait_lines_done aborted the scan. Wrong line or pulse counts still fail.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDyJxbBLmjZCEPUo5FM
The PSO opto output (J7-6/7 sourcing from J7-25 +5 V) into a 50 Ohm input is high
inside the window in both directions (measured on the PandA TTLIN3, 2026-10-29).
DDG1 EXT is 50 Ohm as well, so the tested wiring needs a rising edge. "falling"
stays available for the open collector / differential outputs (not tested).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDyJxbBLmjZCEPUo5FM
A replayed PULSE train also came 1.3 s after an unchanged parameter write by a new
device instance (connect / configure_line), outside the 1 s quiet wait, and blocked
the first line trigger. Fields are now read first and written only if the PandA holds
a different value, so a reconnect on a configured PandA writes nothing; the quiet wait
after a real change is 2 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDyJxbBLmjZCEPUo5FM
Measured with TTL gates on J12 at 2 mm/s: trigger 0 ("UINT1 rising" in the A3200
help) latched at the gate end (+17.2 um for a 10 ms gate, expected +20), trigger 3
at the gate start (-3.0 um). The Npaq UINT input is inverted compared with the help.
Default trigger_input is now 3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDyJxbBLmjZCEPUo5FM
- readout time from the trigger hardware (DDG2 effective_readout_times()["ab"], PandA
  device config readout_time, default 0.2 ms), no scan argument; the trigger positions
  move inward by v * readout / 2 so the gates are centred in their cells and forward /
  backward lines have the same exposure centres
- aerotech_cont_grid always captures the positions (capture_positions removed):
  aerocapture publishes the captured gate starts (enc<ch>) and the exposure centres
  (enc<ch>_centre, + v * gate_width / 2 in the direction of motion)
- statistics at the end of the scan (sent to the client): centre - nominal cell centre
  per direction, backward - forward with slope and peak-peak, scan and line times
- aerox acceleration 500 mm/s^2 (1000 left a speed drift in the lines at 20 mm/s);
  aerocapture enabled, channels X and Y only

Hardware 2026-10-29 (PandA, 0.2 ms readout, 6 snake lines each), backward - forward:
2 mm/s +2.3 / +3.2 um, 0.5 mm/s -0.1 / -0.75 um, no slope; 20 mm/s -1.2 um,
slope -1.2 um/mm (was +24 um, 5 um/mm with 1000 mm/s^2 and no compensation).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDyJxbBLmjZCEPUo5FM
After a hard stop (5 mm/s, 500 mm/s^2) X rings at ~10 Hz with ~20 um. The single
position error check caught a zero crossing (-0.19 um), the move was declared
settled 3.5 um off the target and failed (premove of a scan aborted). Now position
error and distance to the target must stay within the tolerance for
in_position_hold (0.1 s) without interruption.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDyJxbBLmjZCEPUo5FM
As soon as the fast axis has left the exposure range (beyond the trigger position),
the PSO window of the next line is set and the step axis starts; the next line starts
when both have arrived. Saves ~0.15 s per line (2 mm/s, 0.8 mm: 1.07 -> 0.92 s per
line incl. step; 20 mm/s: 0.85 -> 0.65-0.73 s). settle_time stays 0.15 s: shorter
values at 20 mm/s gave -24 / +10 / +4.5 / -21 um backward - forward (0.08 / 0.04 /
0.02 / 0 s), a ~10 Hz oscillation after the ramp.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDyJxbBLmjZCEPUo5FM
fix(panda): rename software_trigger to soft_line_trigger
CI for csaxs_bec / test (push) Successful in 3m34s
e79314c77f
software_trigger is a DeviceBase name in BEC, so the device server refused to
load pandatrig ("User access method name {'software_trigger'} is protected").
New test: USER_ACCESS of the PandA and A3200 devices has no protected names.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
calibrate() returned {channel: offset} with integer keys. The scan server cannot
decode an RPC reply with integer map keys (msgpack strict_map_key), so the
calibrate status never completed and aerotech_cont_grid waited forever in
pre_scan. Now {"enc<channel>": offset}; new test round-trips the RPC return
values of the capture device through the BEC serializer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
fix(aerotech): set_line_trigger_window in USER_ACCESS
CI for csaxs_bec / test (push) Successful in 4m2s
e57ae0ddc6
aerotech_cont_grid switches the PSO window per line through RPC, which only
exposes USER_ACCESS methods: the scan failed after the first line with
"'Positioner' object has no attribute 'set_line_trigger_window'".
New test: every method the scan calls on the fast axis, the capture device and
the PandA is in the device's USER_ACCESS.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
fix(aerotech): scan checks raise alarms so the user sees the reason
CI for csaxs_bec / test (push) Successful in 3m34s
06ce7b0751
The scan worker only logs a ScanAbortion; the client then shows just "Scan ...
was interrupted" (seen 2026-10-29 with the run-up limit check). The checks of
aerotech_cont_grid now raise LimitError (limits), ValueError (parameters,
missing devices) and RuntimeError (missing line trigger), which the scan worker
turns into an alarm with the message, and still runs on_exception.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
aerocapture published the latched positions (and centres) in controller coordinates;
with sign: -1 in the device config they had the opposite sign of the motor readback
and the scan statistics compared different frames. The capture device now looks up
the A3200Motor of each channel (same controller, same axis) on the device server and
applies its sign; without such a motor it keeps sign 1 and logs a warning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDyJxbBLmjZCEPUo5FM
wait_lines_done warned after every line with the total of ignored edges since
arm (20/10, 23/11, 26/13 ... in a 2026-10-29 scan), which read like an
escalating trigger error. These edges are harmless (encoder noise at the PSO
window entry while the line runs; lines and pulses are checked and raise on a
mismatch), so only the edges new since the last line are logged, at info level.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
- scan_info / data file recorded readout_time 0.0 although the gates and the
  centres used the trigger hardware's 0.2 ms; now the value the scan uses
- statistics: "line mean" was line start .. trigger checked (0.60 s for a
  0.78 s line in scan 8477) and "scan" ran from pre_scan only (10.0 s for a
  13.5 s file); now line period start to start incl. capture readout and step,
  with motion / readout split, and the total of the lines labelled as such

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
User guide (SAXS / Aerotech stages): initialisation on the A3200 PC, config,
moves, aerotech_cont_grid with copy-paste examples for the planned fields of
view, run-up and soft limits, data written, timing / positioning section
(results of the 2026-10-29 series pending; overhead and uneven-positions
estimate defined). Developer guide: interface, moves, scan design and measured
choices, position capture, PandABox line trigger, pitfalls, commissioning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
feat(aerotech): minimal_run_up option, run-up only the ramp distance
CI for csaxs_bec / test (push) Successful in 3m39s
3c551ba38e
aerotech_cont_grid(..., minimal_run_up=True): run-up / run-out = v^2 / (2a),
without the 2x margin and settle_time, for analysis with unevenly spaced
(captured) positions; at least 0.01 so the fast axis never stops and reverses
at the edge of the next line's PSO window (0.25 um at 0.5 mm/s otherwise).
Shown in the statistics header and the limit message.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
Opens (or reuses) the GUI window "aerotech" with a Waveform of the async
aerocapture centres, enc2_centre vs enc6_centre, updated per line during
aerotech_cont_grid; scan_number=... shows a finished scan.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
The Waveform's async device curves switch on automatic "peak" downsampling and
clip-to-view above 1000 points; both assume X increasing along the curve, so a
snake scan (8494, 105651 points) showed a diamond pattern and paired markers.
csaxs.aerotech.plot() now reads the scan file (history) or follows the
aerocapture async stream of the running scan (live, from_start, redraw in a
worker thread at <= 2 Hz) and sends plain X/Y data: forward and backward lines
as two curves, points ordered by cell column, alternately up and down, so X
increases along each curve (clip-to-view works when zoomed) and the thin line
runs along the columns. csaxs.aerotech.stop_plot() stops following.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
docs(aerotech): live plot colours, stop_plot
CI for csaxs_bec / test (push) Successful in 3m37s
bff159095c
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
fix(csaxs): aerotech plot shows markers only and reuses its plot
CI for csaxs_bec / test (push) Successful in 3m40s
8c19ed0807
- the column-wise connecting lines suggested a vertical fast axis; a NaN after
  every point now breaks the curve, so only the exposure markers are drawn (X
  stays finite and sorted for clip-to-view)
- a second plot() call added a second Waveform to the window (new() with the
  same object_name does not reuse it); the existing one is now looked up with
  widget_map() and cleared

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
fix(csaxs): aerotech plot stops following once its window is closed
CI for csaxs_bec / test (push) Successful in 3m37s
2c5ea7e6bf
A closed plot made every redraw fail with a warning for each line of each
scan. The first failure now stops following the scans (unsubscribes) with one
message to reopen the plot with csaxs.aerotech.plot().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
Both series of 2026-10-29 (8486-8494 default, 8501-8509 minimal_run_up):
timing and positioning per case, why the saving is about half the shorter
travel (Y step no longer hidden in the run-out), the constant direction
offset after the velocity transient and the 20 mm/s oscillation, deviation
and zoom plots, and the split of the line period with the next levers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
- PandA line trigger: shutter_delay (default 8 ms, as DDG1) between the line
  trigger and the first gate, get/set_shutter_to_open_delay like DDG1; the scan
  now reads it for trigger_source="panda" (was 0, so the test series ran with
  the first gate at the trigger, unlike the beamline)
- a shutter_delay scan argument with "ddg" only moved the trigger positions,
  DDG1 kept its own delay; it is now set on DDG1 before staging and restored
  in post_scan / on_exception
- docs: DDG1/DDG2 timing chain (exp_time = gate period, readout subtracted),
  note that the 2026-10-29 series ran without shutter delay

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
config(sastt): SmarGon goniometer in sastt_aerotech_panda.yaml
CI for csaxs_bec / test (push) Successful in 3m31s
92be444069
Coordinator + SHX/SHY/SHZ/CHI/PHI motors as in smargon.yaml (smargopolo REST
API, host tt-smargopolo, port 3000).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
feat(smargon): readback monitor follows moves made outside BEC
CI for csaxs_bec / test (push) Successful in 3m38s
94d7890aee
The motors only updated their readback at connect and during BEC moves, so a
move in the smargopolo web interface never reached BEC (a read returned the
stored value). The shared controller now polls /readbackSCS (all axes, one
request) every monitor_interval (motor config, default 0.5 s, 0 = off) and
publishes the axes that changed; it skips while BEC moves an axis, logs a
failure once, and stops when the last axis is destroyed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
docs(smargon): monitor_interval in the config key list
CI for csaxs_bec / test (push) Successful in 3m33s
6b49f9eaa3
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
The IPython client prints client-info messages only from a scan's progress
display. With trigger_source="panda" or None the scan registered none, so the
end-of-scan statistics were sent but never shown (scan 8511). The position
capture now publishes a ProgressSignal (lines read / num_points) and the scan
uses it for the progress bar when there is no MCS card.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M8zoDzDfsCTY2o5bT3J7Wv
The scan server builds the Minimum/Full examples itself; ScanArgument(example=...)
now gives aerox / aeroy, a 3.5 x 3 mm field at 40 um and 20 ms. trigger_device
defaults to None (pandatrig with trigger_source="panda"), so the Full example no
longer shows pandatrig next to the default "ddg".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017NrH3poJsYBCTVq2Y9fuHZ
fix(aerotech): park the PSO window once the line is triggered
CI for csaxs_bec / test (push) Successful in 3m47s
CI for csaxs_bec / test (pull_request) Successful in 3m38s
353d6bbb01
At the beamline (DDG1 trigger) every line started two bursts: the window was
switched to the next line when the axis passed trigger_high, just after the DDG1
cycle (as long as the travel trigger_low -> trigger_high), and the edge started a
second burst. MCS and detectors counted twice the frames, so their frames no
longer matched the captured positions (progress bar done at half the scan).

The window is now moved to a parking range beyond the line end as soon as the axis
has entered it, while DDG1 / PandA run the line and ignore edges; the next line's
window is set beyond the exposures as before, outside both windows. The per-line
MCS check also fails on more frames than the line has.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017NrH3poJsYBCTVq2Y9fuHZ
bec_bl_push-gitea added 2 commits 2026-11-03 11:40:09 +01:00
main.yaml loads sastt_aerotech.yaml instead of ptycho_lamni.yaml. aeroz and
aerorot are commented out in sastt_aerotech.yaml (not used at the beamline now).
sastt_aerotech_panda.yaml (PandA test setup without beamline timing) moved to
legacy/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017NrH3poJsYBCTVq2Y9fuHZ
Merge origin/main into feat/aerotech-stages
CI for csaxs_bec / test (pull_request) Successful in 3m46s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 3m36s
12528a8f63
Conflict in cSAXS.py: keep cSAXSDiagnostics(client) from main and the
csaxs.aerotech helper from this branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017NrH3poJsYBCTVq2Y9fuHZ
holler merged commit 12528a8f63 into main 2026-11-03 11:44:23 +01:00
holler deleted branch feat/aerotech-stages 2026-11-03 11:44:23 +01:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: bec/csaxs_bec#351