Commit Graph
10 Commits
Author SHA1 Message Date
x01dcandClaude Sonnet 5 d119bd2ce8 fix(flomni): widen tomo_type-4 angle range to stage overtravel; fix GUI clipping
CI for csaxs_bec / test (push) Successful in 3m4s
Angle files now accept -2 to 362 degrees (the fsamroy rotation stage's
physical overtravel range) instead of the nominal 0-360 sweep. This
required widening both the parser's bounds (angle_file.py) and
_tomo_scan_at_angle()'s own gate (a new _min_scan_angle(), alongside the
existing _max_scan_angle()) -- without the latter, an angle just outside
[0, 360] would have parsed fine but then been silently skipped during
acquisition with no error, which is worse than rejecting it upfront.

Also fixes the type-4 GUI section's "Content:" label clipping its second
wrapped line: QFormLayout sizes that row from the label's sizeHint() at
construction (holding the short "---" placeholder) and doesn't reliably
recompute it when setText() later swaps in longer, word-wrapped content.
_set_angle_file_summary() now recomputes the label's minimum height from
heightForWidth() after every update.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NPZ9gzN2rt3wgiMnTKyrug
2026-10-01 11:49:49 +02:00
x01dcandClaude Sonnet 5 67884c0c3f feat(flomni): tomo_type 4 -- live-appendable angle files, per-line overrides
CI for csaxs_bec / test (push) Successful in 2m59s
Angle files can now be grown while a scan is running: tomo_scan() polls
and re-reads the file whenever it catches up to the current end,
picking up newly appended lines automatically instead of requiring
tomo_scan_resume(). A file is "complete" only once it ends with an
explicit END sentinel line -- without one the scan waits indefinitely
at EOF rather than stopping, so a static/legacy angle file needs END
appended or a scan against it will hang at the end.

Each line may also carry optional step=/exptime=/frames= key=value
tokens overriding the Fermat step size, exposure time, and burst frame
count for that projection and (sticky) every one after it, falling
back to the live tomo_parameters() configuration whenever not set.
Threaded through as kwargs that default to None and are omitted when
empty, so every existing tomo_type 1/2/3 call site and test stub is
unaffected.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NPZ9gzN2rt3wgiMnTKyrug
2026-10-01 11:01:16 +02:00
x01dcandClaude Opus 5.5 9373fe307a fix(flomni): no 0-deg damage-estimation shots for tomo_type 4
CI for csaxs_bec / test (push) Successful in 3m4s
Sub-tomogram numbers in a user angle file are just labels, so inserting
extra 0-deg projections at odd sub-tomogram transitions is surprising.
tomo_type 4 now ignores golden_projections_at_0_deg_for_damage_estimation;
the CLI no longer prompts for it and the widget hides it for type 4.
The unconditional 0-deg reference shot at the start of a new tomogram
is unchanged; further 0-deg shots can be put in the file directly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 14:57:11 +02:00
x01dcandClaude Opus 5.5 35ac94cfd5 feat(flomni): tomo_type 4 -- angles read from a file
CI for csaxs_bec / test (push) Successful in 3m7s
New angular sampling mode: tomo_angle_file points to a plain-text file
with one angle (0-360 deg) per line, optional 2nd column = sub-tomogram
number, '#' comments. Only the path is stored; the file is re-read at
every tomo_scan() start, resume and queued-job run, so an edited file
always takes effect on the next (re)start. The parsed angle list is
logged to scilog at scan start.

- OMNY_shared/angle_file.py: shared pure parser + summary, incl.
  warning for 180-deg-opposite/duplicate angles
- flomni: tomo_type 4 branch in tomo_scan()/tomo_scan_resume(), bad
  file fails before any acquisition, angles >180 not gated by
  tomo_angle_range, CLI prompt/display, PDF report
- tomo queue: path snapshotted per job; setter does not validate so
  stale paths never break non-type-4 jobs; reacquire bounds by file
- TomoParams widget: type 4 (flomni only) with Browse... file dialog,
  live content preview, validation blocking Submit/Add to queue
- webpage: show angle file in param tables

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 14:46:56 +02:00
x01dcandClaude Sonnet 5 337cdc45e9 fix(xrayeye): hide the Skip button until a client script opts in
CI for csaxs_bec / test (push) Failing after 2m57s
LamNI/omny never call enable_skip_button, so they only had a greyed-out
Skip button. Keep it hidden; the first enable_skip_button() call (flomni
does this at the start of the alignment) shows it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 16:10:09 +02:00
x01dcandClaude Sonnet 5 0ad6c5014d feat(flomni): Skip button on the xrayeye alignment to leave out one angle
CI for csaxs_bec / test (push) Failing after 2m12s
Flat samples are edge-on at 90 deg and cannot be centered there. The
XRayEye widget gets a Skip button (disabled unless the client enables it,
so LamNI/omny are unaffected) that signals omny_xray_gui.submit = -1.

XrayEyeAlign._align_impl leaves that step out of the fit: one of the five
angles may be skipped, at least 4 are needed. Skips of the FZP center, the
height marking, or a second angle are refused with a message and the run
continues. write_output() builds angles/offsets from the remaining steps
and raises if fewer than 4 are left; the h5 records the skipped angles.

Not yet tried on real hardware.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 15:56:10 +02:00
x12saandClaude Sonnet 5 26df688512 fix(flomni): motion stop button stops all three Galil controllers
CI for csaxs_bec / test (push) Failing after 2m26s
The GUI "Motion Stop" button did not stop the stages when pressed during
a sample transfer:
- stop_all_axes was not in the Galil controllers' USER_ACCESS, so the
  foptx stop over RPC could never work (only logged in the GUI server).
- fsamroy's controller (port 8084) was never stopped.
- an unresolvable device in _stop_device_controller returned silently.

The widget now takes hard_stop_device_names (flomni: ftransy, foptx,
fsamroy; transfer controller first) and sends stop_all_axes() to each
controller from its own thread, so a hung RPC cannot delay the others.
Devices are resolved freshly at click time with retries, every outcome
is logged and shown in the widget's message label, and positioning mode
is restored on the first controller only after all stops were sent. If
stop_all_axes is not yet exposed by the device server, the raw
XQ#STOP,1 is sent via socket_put_and_receive. The legacy
hard_stop_device_name/extra_hard_stop_device_name kwargs still work.

Not yet tested on hardware.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-21 13:44:06 +02:00
x01dcandClaude Sonnet 5 0690fbb391 feat(flomni): auto-lock ROI vertical center to FZP height in x-ray eye alignment
Implements docs/plans/xrayeye-vertical-lock.md: once the height-centering
step fixes the sample's vertical position against the FZP crosshair, every
selection box drawn for the remaining angle-alignment steps (1-5) no longer
needs manual vertical placement -- it snaps to the crosshair's y position on
draw and again on every drag/resize.

- OMNY_XRayEye: new _vertical_lock_enabled state, lock_vertical_center()/
  unlock_vertical_center() RPC methods, _snap_roi_vertical() helper wired
  into _style_new_roi() (both roiAdded and sigRegionChangeFinished). Snap is
  idempotent (no-op once already at the target y) so it can't loop back into
  itself via its own set_position() call.
- Also added a "ROI vertical lock" toggle in the control panel so an
  operator can release/re-engage the lock manually mid-run -- e.g. to freely
  draw/measure an unrelated box without aborting the alignment. Both the
  toggle and the RPC methods stay in sync (blockSignals pattern already used
  elsewhere in this file for on_live_view_enabled).
- x_ray_eye_align.py: lock_vertical_center() right after _height_centered
  flips to True; unlock_vertical_center() at the start of every fresh run
  (so a run never inherits a stale lock) and in align()'s finally block
  (so the lock never outlives a run, including on error/interruption).

FZP box (step 0) and the height-centering box itself remain fully free --
the lock isn't engaged yet at that point. LamNI/OMNY have their own
near-identical scripts but are explicitly out of scope (per the plan); the
widget change is inert by default.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Lx3KffiFyyDMKT8vvPENUW
2026-09-17 14:22:20 +02:00
wakonig_k 447a9c3924 refactor: upgrade to copier version v1 2025-05-24 11:37:51 +02:00
appel_c c109abce12 feat: populated csaxs_bec from ophyd and bec 2024-04-19 17:48:30 +02:00