Commit Graph
812 Commits
Author SHA1 Message Date
x01dcandholler bcedf794a5 fixes/version2 sim devices
s Please enter the commit message for your changes. Lines starting
2026-07-12 07:52:37 +02:00
x01dcandholler 704826c94a feat(sim): add simulated flOMNI endstation (galil, smaract, rt, cameras)
Protocol-level simulation of the flOMNI hardware injected via socket_cls:
real device/controller classes run unchanged against state machines
implementing fgalil.dmc, galil_micos_upr.dmc, the Smaract MCS protocol
and the Orchestra CommunicationServer. Cameras reuse the real device
classes with a synthetic frame source. Includes simulated_flomni device
config (boots referenced at 'in' positions) and an offline harness
covering moves, referencing, rt feedback/tracker, flyer scan readout
and the gripper transfer routine.
2026-07-12 07:52:37 +02:00
x12saandholler 6722d1573a reset manual shift and auto set fovx after xray align
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 1m34s
2026-07-12 07:28:10 +02:00
x12saandholler e7cc2205cd comment on 0 z shift added 2026-07-12 07:28:10 +02:00
x12saandholler 621cd5aaef feat(flomni): include measurement ID in end-of-tomo scilog summary 2026-07-12 07:28:10 +02:00
x12saandholler 01f74ea4f7 refactor(flomni): consolidate global-var params into _GlobalVarParam descriptor
Replace 11 identical global-var-backed getter/setter property pairs with a
single _GlobalVarParam descriptor. Behavior is unchanged: same keys, defaults,
and None-handling; stitch_x/stitch_y retain int enforcement via the descriptor's
type_ guard (typeguard.check_type). Net -57 lines with no functional change.
2026-07-12 07:28:10 +02:00
x12saandholler 4fe8d02ba0 fix(flomni): warn on invalid beamline states before manual xray-eye frame; fix sample-remove slot handling
xrayeye_update_frame() now checks all configured beamline states and, if any
are not valid, warns the user (the frame may be empty when the beam is down)
and asks before taking a frame. The automated alignment path is unaffected.

ftransfer_sample_change(): clarify the remove-only prompt to "sample currently
in the sample stage", and include tray slot 20 in the empty-slot scan
(range(1, 20) -> range(1, 21)) in both the remove and mount branches, matching
check_position_is_valid's 0-20 range.
2026-07-12 07:28:10 +02:00
x12saandholler f435739c7f docs fix 2026-07-12 07:28:10 +02:00
x12saandholler 90ded9305a print green bold 2026-07-12 07:28:10 +02:00
x12saandholler 5ac695afe6 print fov bold 2026-07-12 07:28:10 +02:00
x12saandholler 0facd37860 better timing printout end of tomogram 2026-07-12 07:28:10 +02:00
x12saandholler 019693c5c8 scilog command changed 2026-07-12 07:28:10 +02:00
x12saandholler eef4e84bc9 feat(flomni): log projection timing from direct tomo_scan_projection calls 2026-07-12 07:28:10 +02:00
x12saandholler 0fe92c3efb feat(flomni): skip feye_out in tomo_alignment_scan when scan-ready
When the eye is already out, optics in, and feedback running, skip the
eye-out/optics-in transition to avoid an interferometer reset. Enables
repeated alignment scans and interleaving alignment into a tomogram
without leaving the current measurement position.
2026-07-12 07:28:10 +02:00
x12saandholler 6d5feb0d49 fix(flomni): skip feedback reset in ffzp_in when FZP already in
feedback_disable/enable_with_reset cycle re-zeros the interferometers
and moves off the current sample position. Only run it when the FZP
actually needs to move; add force_feedback_reset kwarg and _ffzp_is_in
helper.
2026-07-12 07:28:10 +02:00
x12saandholler 38431d9ebf feat(flomni): live ROI size readout and camera-sourced pixel calibration
X-Ray Eye alignment GUI + script now share a single, device-configured
pixel calibration and the GUI shows live ROI dimensions.

GUI (x_ray_eye.py):
- Add read-only "ROI size" field below the message box, showing the active
  ROI's x/y extent, updated live via each ROI's sigRegionChanged. Rectangles
  report width/height; circular ROIs read raw state["size"] so an ellipse
  state would be reflected (currently aspect-locked upstream).
- Add "Calibration" field showing microns/pixel, or "uncalibrated (pixels)"
  when the camera parameter is absent.
- Resolve mm/pixel from dev.cam_xeye.user_parameter["pixel_calibration"];
  fall back to raw pixels (scale 1.0, unit "px") if unavailable.
- Enlarge the message field from 60 to 90 px height.

Alignment script (x_ray_eye_align.py):
- Replace the hard-coded PIXEL_CALIBRATION constant with a pixel_calibration
  property reading the same cam_xeye user parameter; fall back to
  PIXEL_CALIBRATION_DEFAULT if unavailable.
- Fold the recurring factor of 2 into the calibration: xval_x_* come straight
  from raw ROI pixels on submit, so the true scale is 0.05/113 mm/pixel.
  Default is now 0.05/113 and the three /2 factors (FZP center x, height
  centering, FOV) are removed. Computed physical values are unchanged.

Device config (cam_xeye_pixel_calibration.yaml):
- Add pixel_calibration userParameter (0.05/113 mm per raw ROI pixel) to
  cam_xeye. Merge the userParameter block into the existing device entry.
2026-07-12 07:28:10 +02:00
x12saandholler 4181a4fcb2 feat(flomni): comment-first scilog_last_scans, comment-only mode, no logo
scilog_last_scans now puts the user comment at the top of the entry and
drops the flOMNI logo attachment. number_of_scans accepts 0 to send a
comment-only entry. When fewer projection records exist than requested
(e.g. non-ptycho scans, which write no timing record), the available ones
are used and a note reports how many of the requested count were found.
2026-07-12 07:28:10 +02:00
x12saandholler 475704c16b feat(flomni): offer tomo-param reset on account change at session start
At BEC session start, compare bec.active_account against the new global
var defaults_applied_for_account. On a genuine account change, interactively
offer to reset all tomo scan parameters to their defaults for the new
experiment; a client restart within the same account is a silent no-op.
Add _set_default_tomo_params() writing all 20 scan parameters via the
property setters.
2026-07-12 07:28:10 +02:00
x12saandholler bedf61e0ab fix/recon folder name from global var was not set when changed in gui 2026-07-12 07:28:10 +02:00
x12saandholler 47e3d59164 added ES shutter to ES config 2026-07-12 07:28:10 +02:00
x12saandholler f8f655aa08 config update 2026-07-12 07:28:10 +02:00
x12saandholler 7e437ae24f replace yesno with gui yesno 2026-07-12 07:28:10 +02:00
x12saandholler 956d1ad1bc - ConsoleButtonsWidget ABORT: SIGINT to the client (only if the parent
process looks like a BEC client), plus a delayed (500 ms) backup
  stop_devices request, defaulting to stop-all so the widget doubles as
  a generic emergency stop when opened standalone from the launcher menu
2026-07-12 07:28:10 +02:00
x12saandholler 27932cc552 feat(flomni): make sample transfer abortable via Ctrl+C and GUI abort button
The gripper routines (#GRGET/#GRPUT) run autonomously on the Galil
(thread 3); Ctrl+C previously only killed the BEC-side polling loop
while the controller kept executing, including ongoing motion.

- add FlomniSampleTransferMixin.ftransfer_abort(): dev.ftransy.stop()
  (stop_devices endpoint -> device server -> XQ#STOP), wait for thread 3
  to halt, then put the controller back in posmode; deliberately no
  ensure_gripper_up() - recovery after an abort is manual
- wrap the mntprgs polling loops in ftransfer_get_sample/put_sample in
  try/except KeyboardInterrupt -> ftransfer_abort()
- answering "No" at a confirmation point now also hard-aborts the
  controller routine instead of leaving it parked in #CONFIRL
- ConsoleButtonsWidget ABORT: keep SIGINT to the client, plus a delayed
  (500 ms) backup stop_devices request so the hardware stops even if
  the client is hung; delay ensures the controlled client-side abort
  wins the race against #STOP clearing mntprgs
2026-07-12 07:28:10 +02:00
x12saandholler f583bb336b feat(bec_widgets): grey out Yes/No in ConsoleButtonsWidget when no message
Yes/No start disabled and are enabled only while a message is set; ABORT
stays always enabled. Clear visual cue that there's nothing to confirm.
2026-07-12 07:28:10 +02:00
x12saandholler c11cc24fcd minor fix gui confirm 2026-07-12 07:28:10 +02:00
x12saandholler c044d2b6c1 feat(flomni): add GUI confirm/abort console for sample transfer
Add a small ConsoleButtonsWidget (Yes/No/Abort + message label) as a
GUI alternative to console yesno() prompts during sample transfer,
docked below the live camera view.

- bec_widgets: new ConsoleButtonsWidget (csaxs_bec/bec_widgets/widgets/
  console_buttons/). Yes/No write to a response property polled by the
  caller; Abort sends a real SIGINT to the BEC client process (captured
  via os.getppid() at construction), stopping any blocking call
  (including an in-progress motor move) exactly like a console Ctrl+C.

- omny_general_tools: add OMNYTools.gui_yesno(), a GUI-backed
  alternative to yesno() with the same message/default/autoconfirm
  semantics, polling the widget's response instead of blocking on
  input(). Not yet used as a general yesno() replacement.

- gui_tools: flomnigui_show_cameras() now also opens the console widget
  docked below the two camera views (set_layout_ratios for relative
  sizing, since dock_area.new() has no pixel width/height kwarg).
  flomnigui_show_gui() now passes an explicit window geometry, right-
  aligned on a 2560x1440 screen.

- flomni: add ftransfer_confirm_dialog(), which uses the GUI console
  when available (falling back to the plain CLI yesno() otherwise) and
  wire it into ftransfer_confirm()'s per-step "All OK? Continue?"
  prompt during sample transfer. Other yesno() call sites (stage-in
  flight-tube check, gripper-move stage-out check) intentionally left
  on the CLI for now.

Known issue: requested window height in flomnigui_show_gui() is not
taking effect as expected at startup; needs follow-up.
2026-07-12 07:28:10 +02:00
x12saandholler 439f3b9e2c reverse numbering 2026-07-12 07:28:10 +02:00
x12saandholler 10eb949206 feat(flomni): add remove-only sample change via ftransfer_sample_change(-1)
Passing -1 stows the sample currently in the sample stage into a free
tray slot without mounting a replacement, matching the old control
system's sample_change(-1) behavior. Existing swap-path logic is
unchanged.
2026-07-12 07:28:10 +02:00
x12saandholler e7c10d3727 feat(flomni): acquire empty frames at start of tomo_scan
Add collect_empty_frames(), which acquires 10 flat-field frames at
angle 0 with fsamx shifted out of the beam by fovx/2 (opposite the
normal alignment x-offset). Called once at the start of a new
tomo_scan() (not on resume). Frames are excluded from the ptycho
reconstruction queue and logged to tomography_scannumbers.txt with
subtomo_number=0.
2026-07-12 07:28:10 +02:00
x12saandholler 040468968f flomni: add laser_parameters CLI and laser_tweak tool
Expose the ConstEmitter runtime constants through the high-level flomni
interface, alongside the existing laser_tracker_* methods, and add an
interactive tweak tool for the two tracking target positions.

New methods on FlomniSampleTransferMixin (thin wrappers delegating to
dev.rtx.controller, same pattern as laser_tracker_show_all):
  laser_parameters_show_all()
  laser_parameters_set_targety(val)
  laser_parameters_set_targetz(val)
  laser_parameters_set_intensity_threshold_laser(val)
  laser_parameters_set_psd_intensity_threshold_tracking_low(val)

laser_tweak(): interactive 2D raw-terminal loop for the two tracking targets,
modeled on OMNYTools.tweak_cursor.
  left/right : target y -/+   (fixed 0.01 step, absolute set of current +/- step)
  up/down    : target z +/-
  s          : return both targets to their launch positions
  q          : quit (terminal state restored in finally)
On launch and after every change it prints the current y/z targets and the
fzp x interferometer signal (read_ssi_interferometer channel 1), so the signal
response can be watched while tweaking.

termios/tty/fcntl/sys are imported locally in laser_tweak to avoid touching
module-level imports. Additive change; no existing behaviour modified. Requires
the ConstEmitter emitter_* methods on RtFlomniController.
2026-07-12 07:28:10 +02:00
appel_c 804ffef5b0 feat(saxs-widget): Add SAXS Widget for scanning SAXS and Tensor Tomography measurement setup
CI for csaxs_bec / test (pull_request) Successful in 1m31s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 1m34s
2026-07-10 16:54:37 +02:00
appel_c 46a05b48e0 fix(cont-grid): add extra point in lines to include endpoint 2026-07-10 16:53:14 +02:00
wakonig_k 277a54b913 Updating to template version 1.4.1
CI for csaxs_bec / test (pull_request) Successful in 1m33s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 1s
CI for csaxs_bec / test (push) Successful in 1m32s
2026-07-07 14:19:19 +02:00
x12saandholler 94ac7238b1 perf(bec_widgets): fix SampleStorageWidget poll lag
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 1s
CI for csaxs_bec / test (push) Successful in 1m32s
Replace ~44 per-slot blocking device reads per poll with a single bulk
flomni_samples.read(), and add change-detection so cells only repaint
when their state actually changes. The old per-slot accessors stalled
the GUI event loop every 2s; steady-state polling now does no UI work.
Writes invalidate the changed slot's cache so local edits still repaint
immediately.
2026-07-07 10:44:43 +02:00
x12saandholler 02373c47be feat(bec_widgets): add SampleStorageWidget for flOMNI sample storage
GUI for ftransfer_show / ftransfer_modify. Displays the
sample stage (0), gripper (100) and magazine slots 1-20 in a 4x5 grid
matching the CLI layout. Right-click per slot corrects the records
(new / rename / clear), each action confirmed by its own dialog and
written immediately. Bookkeeping only: writes flomni_samples directly
(mirroring flomni_modify_storage_non_interactive), never moves hardware.
Guarded on fsamroy; OMNY shows a not-implemented placeholder.
2026-07-07 10:44:43 +02:00
x12saandholler 12febe2e3a rt_flomni: add ConstEmitter client access to RtFlomniController
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 1m31s
Expose the flOMNI ConstEmitter runtime constants (served over the control-loop
TCP server, command letter 'e') to BEC users. These were previously baked into
Orchestra module parameter files; they can now be read and set live.

New RtFlomniController methods (all added to USER_ACCESS):
  emitter_get()                                  -> dict of the four values
  emitter_show_all()                             -> PrettyTable printout
  emitter_set_tracking_target_y(val)             -> "ey<val>"
  emitter_set_tracking_target_z(val)             -> "ez<val>"
  emitter_set_intensity_threshold_laser(val)     -> "et<val>"
  emitter_set_psd_intensity_threshold_tracking_low(val) -> "el<val>"

emitter_get issues "es" and parses the CSV reply
(targetpos_tracking_y, targetpos_tracking_z, intensity_threshold_laser,
PSD_intensity_threshold_tracking_low), same pattern as the Ts/sr readouts.
Setters use socket_put with a fixed %.4f value, same pattern as the pa
setpoint command; they are fire-and-forget (the server does not ack sets).

The rotation-loop laser threshold (intensity_threshold_rot_laser) is a startup
constant on the server side and is intentionally neither read back nor settable
here.

Named methods were chosen over a single opaque command to match the existing
laser_tracker_* / feedback_* convention and to self-document each value.

Requires the corresponding flOMNI control-loop change (ConstEmitter module +
'e' command in CommunicationServer). Additive change; no existing behaviour
modified.
2026-07-07 10:41:40 +02:00
x12saandholler 081e8db8af flomni: add laser_parameters CLI and laser_tweak tool
Expose the ConstEmitter runtime constants through the high-level flomni
interface, alongside the existing laser_tracker_* methods, and add an
interactive tweak tool for the two tracking target positions.

New methods on FlomniSampleTransferMixin (thin wrappers delegating to
dev.rtx.controller, same pattern as laser_tracker_show_all):
  laser_parameters_show_all()
  laser_parameters_set_targety(val)
  laser_parameters_set_targetz(val)
  laser_parameters_set_intensity_threshold_laser(val)
  laser_parameters_set_psd_intensity_threshold_tracking_low(val)

laser_tweak(): interactive 2D raw-terminal loop for the two tracking targets,
modeled on OMNYTools.tweak_cursor.
  left/right : target y -/+   (fixed 0.01 step, absolute set of current +/- step)
  up/down    : target z +/-
  s          : return both targets to their launch positions
  q          : quit (terminal state restored in finally)
On launch and after every change it prints the current y/z targets and the
fzp x interferometer signal (read_ssi_interferometer channel 1), so the signal
response can be watched while tweaking.

termios/tty/fcntl/sys are imported locally in laser_tweak to avoid touching
module-level imports. Additive change; no existing behaviour modified. Requires
the ConstEmitter emitter_* methods on RtFlomniController.
2026-07-07 10:41:40 +02:00
x12saandholler 61b6807594 webpage_generator: keep scanning->blocked silent (no scan-stopped warning)
A block is external and self-resolving, so the immediate "measurement stopped,
confirm" warning chime was misleading there - the user cannot act on it and
should just wait. Suppress startWarning when the destination status is blocked;
the blocked track still handles it (silent until the 60-min blockedChime, then
hourly). scanning->idle (success tone) and scanning->other (warning tone) are
unchanged. Help text updated.
2026-07-07 10:41:40 +02:00
x12saandholler 50084d0ce9 config update 2026-07-07 10:41:40 +02:00
x12saandholler d880431a5a webpage_generator: success chime on finish + trim mobile empty scroll space
- Audio: a normal finish (scanning -> idle) now plays a rising success
  arpeggio (C5-E5-G5) instead of the falling warning chime, so a completed
  measurement is audibly distinct from a stop to any other state (which keeps
  the falling 660->440 warning). startWarning(finished) selects the chime for
  both the initial tone and the 30s repeats; the Watch LED text reads
  "Measurement finished" vs "Measurement stopped" accordingly. Help text
  updated.
- Layout: body uses min-height:100dvh (with 100vh fallback) so the page no
  longer extends below the visible viewport on mobile, where iOS 100vh counts
  the retracted-toolbar height and leaves empty scroll room at the bottom.
2026-07-07 10:41:40 +02:00
x12saandholler 6222cafb62 webpage_generator: instrument pane shows full live measurement parameters
The instrument-details pane showed only a hand-built 6-row settings summary,
far less than the tomo queue shows per job, and nothing useful for a tomo
started outside the queue.

- Flomni _collect_setup_data now returns current_params: the tomo parameters
  read live from global vars, keyed by the same names the queue stores in
  job.params (_CURRENT_PARAM_KEYS, matching TQ_PARAM_DISPLAY). Values left raw;
  the page formats them. Replaces the old settings dict.
- Extract the queue's param-table builder into a shared buildParamRows() JS
  helper (carries the computed Projections row), used by both the queue and the
  new instrument 'Current measurement' section, so they can't drift.
- renderInstrument renders current_params via buildParamRows (Sample name row
  first); card hides only when there are neither params nor temperatures.
- Base _collect_setup_data contract updated: settings -> current_params.
2026-07-07 10:41:40 +02:00
x12saandholler 60cc50bad1 feat(flomni): guard umvr_fsamy_tracked against enabled rt feedback
umvr_fsamy_tracked/umv_fsamy_tracked require feedback OFF but did not
enforce it. Add an _internal flag; for user/CLI calls, warn that feedback
must be off (active alignment may be lost), prompt (default yes), and
disable feedback on confirm. Internal callers pass _internal=True since
they already manage the feedback lifecycle (ftransfer_flomni_stage_out,
x_ray_eye_align height-centering and mvy jog).
2026-07-07 10:41:40 +02:00
x12saandholler 473993617b fix timeout at end of acqusition 2026-07-07 10:41:40 +02:00
x12saandholler 8f2a1a3f78 fix(flomni): use _flomnigui_is_missing guard in show_cameras
Match the deleted-widget detection used by all other flomniGuiTools
methods. The previous _flomnigui_check_attribute_not_exists path relied
on hasattr(self.gui.flomni, "Image"/"Image_0"), which returns stale/
mismatched results when docks are recreated, leaving an empty window
after a user closed the GUI mid sample-transfer. _is_deleted() checks
registry membership and reliably triggers a rebuild.
2026-07-07 10:41:40 +02:00
x12saandholler 7869d84927 fix: add timeout to MCS card status checks to prevent deadlock 2026-07-07 10:41:40 +02:00
x12saandholler 5a00822294 webpage_generator: tomo queue - don't reopen a manually collapsed running job
renderTomoQueue auto-opened the running job whenever the open-state snapshot
was empty, so collapsing the only open job (the running one) made the snapshot
empty and re-opened it on the next refresh. Open-state was also keyed by
positional index, which mis-assigns the flag when jobs are added/removed/
reordered.

- Snapshot open jobs by stable key (added_at|label) via a data-key attribute
  instead of positional index.
- Auto-open a running job only once, on first appearance, tracked in
  window.__tqAutoOpened; afterwards honor the DOM snapshot so a manual collapse
  sticks. Prune the set when jobs disappear.
2026-07-07 10:41:40 +02:00
x12saandholler c50ac5c30c webpage_generator: report blocked on interlock even when scan is interrupted
A block interrupts the running scan, clearing active_request_block, so
the old _derive_status() (which only returned 'blocked' inside the
queue_has_active_scan branch) fell through to 'idle' with the blocked
LED off, despite watched beamline states being out of spec.

- _derive_status: return 'blocked' on beamline_blocking OR queue_locks,
  independent of active scan; only fresh-heartbeat 'scanning' outranks it.
- _cycle: beamline_blocking = enabled is True AND any(state mismatched).
  Gated on enabled so a disabled/unknown interlock with an out-of-spec
  state does not raise BLOCKED. Also counted as activity so the idle
  clock restarts once cleared.
- beamline-states card summary updated in lock-step: mismatched states are
  only called "currently blocking" when enabled, else "out of spec
  (interlock disabled/unknown, not blocking)", so pill and card can't
  disagree.
- status-detail JS: describe blocking beamline states when no explicit
  queue lock is present. Update help text.
2026-07-07 10:41:40 +02:00
x12saandholler 524c26f706 webpage_generator: make tomo-queue and tomo-type formula setup-configurable
webpage_generator: report blocked on interlock even when scan is interrupted

- Add HAS_TOMO_QUEUE and TOMO_TYPES capability flags to
  WebpageGeneratorBase, defaulting to flomni's current behavior
  (type1 grid-8, type2/3 golden-capped) so this is a no-op for flomni.
- Gate the tomo_queue global-var read in _cycle() behind
  HAS_TOMO_QUEUE; unaffected: queue_status/queue_locks/beamline_states,
  which come from BEC's own primary scan queue and stay common to
  all setups.
- _render_html() now conditionally emits the 'Tomo queue' card and
  its DEFAULT_ORDER slot, and drives the projection-count formula
  from a TOMO_TYPES JSON blob (generic calcProjections()) instead of
  a hardcoded per-instrument JS branch.
- LamniWebpageGenerator: HAS_TOMO_QUEUE=False, TOMO_TYPES with
  2-subtomo and 8-subtomo equally_spaced_grid entries (placeholder
  keys pending real tomo_type values from the LamNI producer side).

A block interrupts the running scan, clearing active_request_block, so
the old _derive_status() (which only returned 'blocked' inside the
queue_has_active_scan branch) fell through to 'idle' with the blocked
LED off, despite watched beamline states being out of spec.

- _derive_status: return 'blocked' on beamline_blocking OR queue_locks,
  independent of active scan; only fresh-heartbeat 'scanning' outranks it.
- _cycle: compute beamline_blocking = any(state mismatched), defined
  identically to the beamline-states card so pill and card can't disagree;
  also count it as activity so the idle clock restarts once cleared.
- status-detail JS: describe blocking beamline states when no explicit
  queue lock is present. Update help text."
2026-07-07 10:41:40 +02:00
x12saandholler a20508c878 docs update 2026-07-07 10:41:40 +02:00