Commit Graph
1053 Commits
Author SHA1 Message Date
x01dcandClaude Sonnet 5 1cbfdc40ea docs(flomni): add design plan for Brother P-touch label printer integration
Feasibility/design session output: print account+date labels on
sample-tray unload via P-touch Template mode, as a shared OMNY_shared
utility rather than an ophyd device.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UGC1TfxZJvJHs6Qz1V8w1h
2026-08-19 12:03:18 +02:00
x01dcandClaude Sonnet 5 8936071766 fix(flomni): stop OSA collision at fosa_in(), correct stale foptz init position
CI for csaxs_bec / test (pull_request) Successful in 1m45s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 1m44s
fosa_in() moved fosax/fosay/fosaz straight to their configured "in"
positions with no collision check. ffzp_info() already computed OSA-to-pin
clearance but never gated the move on it. Add a shared
_osa_remaining_space() helper (also used to deduplicate ffzp_info()'s own
calculation) and raise FlomniOpticsError in fosa_in() when the computed
clearance at the target position is <= 0.

Root cause of the specific collision seen: stage init's _align_setup()
hardcoded foptz to 23 instead of its calibrated "in" value of 17
(ptycho_flomni.yaml), 6 mm off from what fosaz's own "in" calibration
assumes. Hardcode foptz to 17 instead, and lock foptz.limits to +-0.1 mm
around it in both set_limits() and _align_setup() so any future move away
from 17 requires deliberately widening the limits first. Also corrects
the stale "in: 23" in ptycho_flomni.yaml's foptz userParameter to 17.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-19 10:15:52 +02:00
x01dcandClaude Sonnet 5 308b4edacd fix(flomni): abort sample transfer when stage-out is declined
CI for csaxs_bec / test (push) Successful in 1m45s
ftransfer_gripper_move() silently returned on "No" to the stage-out
confirmation, but its return was indistinguishable from success to its
callers (ftransfer_get_sample/ftransfer_put_sample), which then proceeded
to command the physical get/mount sequence on the controller -- moving
the gripper without the stage ever having moved out or the gripper being
positioned at the transfer coordinates. Now raises FlomniError instead,
which propagates out of both callers and stops the transfer before any
controller command is sent.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 15:19:17 +02:00
x01dcandClaude Sonnet 5 0a2c6a429c docs(omny_shared): update webpage-upload doc for omny.psi.ch cutover
CI for csaxs_bec / test (pull_request) Successful in 1m46s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 3s
CI for csaxs_bec / test (push) Successful in 1m44s
Reflects the single-URL omny.psi.ch config (myfritz/omny-test list retired)
and replaces the omny-test.psi.ch-specific .svg note with the known
permission and intermittent-WAF issues on omny.psi.ch.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 14:54:57 +02:00
x01dcandClaude Sonnet 5 50d4f8e425 feat(flomni,lamni): repoint all omny endpoints from myfritz/omny-test to omny.psi.ch
CI for csaxs_bec / test (push) Successful in 1m51s
Cuts over the webpage status-page mirror, TomoIDManager's sample-counter
registration, and the samples-folder PDF upload to omny.psi.ch exclusively,
replacing v1p0zyg2w9n2k9c1.myfritz.net and omny-test.psi.ch everywhere.

Note: omny.psi.ch currently has known server-side issues (a permission
error on /upload.php, and a WAF blocking /samples/* outright) tracked
separately with PSI admins -- this switch is expected to be broken until
those are fixed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 14:42:10 +02:00
x01dcandClaude Sonnet 5 6bb8d8027d feat(flomni,lamni): mirror status-page uploads to omny.psi.ch
CI for csaxs_bec / test (push) Successful in 1m45s
Add omny.psi.ch as a third upload target alongside production and the
omny-test.psi.ch trial mirror.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 13:24:54 +02:00
x01dcandClaude Sonnet 5 5af6f82bb1 feat(bec_widgets): add data_viewer widget; rename OMNY widget classes
CI for csaxs_bec / test (pull_request) Successful in 1m57s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 1m48s
Add DataViewer, ported from debye_bec's bec_widgets/widgets/data_viewer,
adapted to this repo's parent()-first __init__ convention required by
bw-generate-cli.

Drop the "Widget" suffix from SampleStorage, SlitControl, and TomoParams
for naming consistency with DataViewer, then further rename for OMNY
namespacing and Designer-list ordering:
- SampleStorage -> OMNY_SampleStorage
- TomoParams -> OMNY_TomoParams
- XRayEye -> OMNY_XRayEye (XRayEye2DControl untouched)
- ConsoleButtonsWidget -> z_ConsoleButtonsWidget (sorts last)

Update the live gui.<area>.new("...") string-based widget lookups in
flomni/LamNI gui_tools.py that construct XRayEye/ConsoleButtonsWidget by
name, so they keep resolving after the rename. Delete now-stale generated
plugin/register/pyproject trios and regenerate everything via
`bw-generate-cli --target csaxs_bec` (client.py, designer_plugins.py, and
fresh per-widget trios under the new snake_case names).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VZHQaRmthXmyfn2pxP3dF9
2026-08-17 17:20:21 +02:00
x01dcandClaude Sonnet 5 67769d5ff8 fix(flomni,lamni): use .get() in tomo_queue_show()'s job-line formatter
CI for csaxs_bec / test (pull_request) Successful in 2m14s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 1m49s
A job's params dict only has whatever _TOMO_SCAN_PARAM_NAMES held when it
was snapshotted by tomo_queue_add(); a job persisted before a key was
added (e.g. fovx/fovy, tomo_circfov) raised KeyError on the hard p['key']
lookup, making the whole queue un-inspectable instead of just missing a
field.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-17 15:47:51 +02:00
x01dc 75cd5d0d00 fix(flomni,omny): expose motor tolerance to scan-server device proxy
CI for csaxs_bec / test (pull_request) Successful in 1m54s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 1m56s
self.dev.fsamroy/.osamroy on the scan server is a generic bec_lib
Positioner proxy rebuilt from serialized device info, not the real
ophyd instance. tolerance was only a plain __init__ attribute, so it
was dropped during serialization and flomni_rotation()/rotation()
crashed with AttributeError: 'Positioner' object has no attribute
'tolerance'. Register tolerance in USER_ACCESS so it serializes and
is reachable via RPC like controller already is.
2026-08-17 11:31:04 +02:00
x01dcandClaude Sonnet 5 4ac20013b8 fix(tomo_params): debounce beamline-busy banner to stop flicker
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 1m49s
_refresh_busy_banner() toggled the banner's visibility synchronously
on every poll tick and scan-queue push message, so brief blips in the
underlying queue status made it flicker on/off.

Show busy immediately, but hold the banner up for 5s of continuous
idle before clearing it, mirroring the debounce pattern already used
for XRayEye's queue-guarded toggles (_queue_idle_timer).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-14 10:52:33 +02:00
x01dcandClaude Sonnet 5 abb933e10d fix(tests): patch input() where yesno() actually calls it
CI for csaxs_bec / test (pull_request) Successful in 1m52s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 1m48s
find_rotation_center()'s y/n prompts now go through OMNYTools.yesno()
(omny_general_tools.py) instead of a raw input() in x_ray_eye_align.py,
but these tests were still patching input() on the old module -- so
the real input() got called under pytest's captured stdin and raised
"reading from stdin while output is captured".

Patch input() on omny_general_tools instead, where yesno() actually
calls it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-14 10:39:12 +02:00
x01dcandClaude Sonnet 5 f0152fe028 fix(lamni,omny): consolidate ad-hoc y/n prompts onto OMNYTools.yesno()
CI for csaxs_bec / test (push) Failing after 1m44s
CI for csaxs_bec / test (pull_request) Failing after 1m44s
Several confirmation prompts hand-rolled their own input() parsing
instead of using the established yesno() helper, including one
weaker variant (no default, no retry, case-sensitive) and a "Close
the shutter now?" prompt duplicated verbatim four times.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-13 14:46:49 +02:00
x01dcandClaude Sonnet 5 4c3c86183a fix(galil): poll thread 0 idle instead of guessing a sleep before XQ#FES/FRM
CI for csaxs_bec / test (pull_request) Successful in 1m53s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 1s
CI for csaxs_bec / test (push) Successful in 2m25s
XQ#NEWPAR dispatches asynchronously on controller thread 0 and returns as
soon as it starts, not once it finishes; the dispatch time varies with
controller load. drive_axis_to_limit/find_reference followed it with a
fixed sleep before starting XQ#FES/XQ#FRM (also thread 0), which has
already needed bumping twice (0.1->0.3, 0.3->0.2) and still raced on
lgalil: sending XQ#FES while thread 0 was still busy got a '?' reply
(Galil error 19, thread already running).

Replace the fixed sleep with _wait_for_thread_idle(0), reusing the
existing is_thread_active() primitive (already used the same way in
hard_abort_and_restore_positioning_mode) to poll until thread 0 is
actually free before dispatching the next routine.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-12 23:28:09 +02:00
x01dcandClaude Sonnet 5 bdb65d0326 fix(smaract): stop mangling GCLS/GPL/GST/etc. replies with str.strip()
str.strip(prefix) strips individual characters, not a literal prefix, so
replies made entirely of characters in the prefix (e.g. ":CLS0,0" for
losax) collapsed to '' and crashed float('') in describe(). Other replies
could silently truncate to a wrong value instead. Since the prefix is
already validated by _message_starts_with(), removeprefix() is a safe
drop-in fix for all affected parsers in SmaractController.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-12 23:28:09 +02:00
wyzula_j 34e7dff17d ci: pytest-cov migrated to coverage
CI for csaxs_bec / test (pull_request) Successful in 1m55s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 2m28s
2026-08-12 17:34:33 +02:00
x12sa 13ab2d5f42 change PV names of slits in optics hutch
CI for csaxs_bec / test (pull_request) Successful in 4m24s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 5m15s
2026-08-04 15:18:00 +02:00
x01dcandClaude Sonnet 5 0e7ef10eee fix(lamni,flomni,omny): stop force-opening tomo-queue panel of running job
CI for csaxs_bec / test (pull_request) Successful in 1m49s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 1m47s
The status webpage's tomo-queue accordion auto-expanded a job's details
panel as soon as its status became "running", overriding whatever
open/closed state the user had selected. Panel state now depends only
on the existing DOM snapshot of user selections.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-31 13:38:13 +02:00
x01dc badbb82ba4 fix(lamni,flomni,omny): re-issue rotation after an interrupted move instead of skipping
CI for csaxs_bec / test (push) Successful in 1m52s
A Ctrl+C during lsamrot/fsamroy/osamroy rotation leaves the cached
user_setpoint at the target even though the axis never finished moving
(stop() halts the motor mid-move). The next scan then wrongly concluded
"no rotation required" from setpoint equality alone, leaving LamNI's
air bearings unclamped (confirmed via galil show all) and the beamline
unable to scan until the setpoint was nudged manually.

lamni_rotation() now also requires
lgalil_is_air_off_and_orchestra_enabled() before skipping, since that
flag only goes true once the Galil #CENROT sequence (air-clamp plus
centering) has fully completed. flomni_rotation()/omny_rotation() use
a readback-vs-tolerance check instead, since those axes have no
air-bearing clamp step.

Along the way, fixed lgalil_is_air_off_and_orchestra_enabled() itself:
it did bool(socket_put_and_receive(...)) directly on the raw Galil
reply string, which is always truthy, so it could never report
anything but True. Confirmed via HW testing in LamNI.
2026-07-31 13:26:15 +02:00
x01dc a082a8cffa remove sample name querry, already done at coarse align 2026-07-31 12:49:46 +02:00
x01dc 59c7906ba7 docs update 2026-07-31 12:49:23 +02:00
x01dc 171481928a docs update 2026-07-31 12:49:13 +02:00
x01dcandClaude Sonnet 5 48b9f893ab fix(lamni,flomni): suppress spurious 0-deg damage-estimation shot on golden-ratio resume
CI for csaxs_bec / test (push) Successful in 1m48s
previous_subtomo_number resets to -1 on every tomo_scan() call in the
golden-ratio branches (tomo_type 2/3), including a resume. That makes
the first loop iteration look like a genuine sub-tomogram transition,
firing the 0-deg reference shot before the actual resume angle even
though the rotation isn't passing through 0 deg at that moment.

Mirrors tomo_type 1's existing start_angle-is-None resume guard:
suppress the shot only for the first, possibly-spurious transition
right after a resume, then let later genuine transitions in the same
call fire normally. Same fix applied to both lamni.py and flomni.py,
which share byte-for-byte identical golden-ratio logic here.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-31 12:43:30 +02:00
x01dcandClaude Sonnet 5 7caf57cff6 feat(lamni): check measurement configuration before tomo_scan()
Flomni's tomo_scan() warns and prompts if the X-ray eye isn't out and
the FZP/OSA optics aren't in before scanning; LamNI had no equivalent,
letting a tomogram start with the eye still in the beam or the optics
retracted. Ports the same check, wired into the existing
force/interactive gating so it never blocks on input() during
unattended/queued runs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-31 12:42:49 +02:00
x01dcandClaude Sonnet 5 1db9c18e0a fix(lamni): drop redundant 45deg detour in smear verification sweep, widen GUI retry budget
CI for csaxs_bec / test (push) Successful in 1m51s
find_rotation_center_smear_experimental() rotated 45->0 for its post-shift
verification sweep, needlessly re-treading ground the preceding full smear
sweep already covered and adding a long extra blocking move that could
starve the GUI heartbeat past _gui_call_with_retry's budget, surfacing as
RuntimeError: GUI is not alive. Sweep straight back to 0 instead, and widen
the retry budget (8x1.5s -> 25x2.0s) so update_frame() can ride out long
blocking moves on slower hardware.

Also tidy a stray comment-block artifact in ptycho_lamni.yaml and update
lamni.md docs for the current xrayeye_rotation_center_calibration_* API.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-31 11:54:07 +02:00
x01dcandClaude Sonnet 5 fa30e11b3c fix(lamni): tolerate transient GUI heartbeat race, fix sample-name prompt order
CI for csaxs_bec / test (pull_request) Successful in 1m46s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 1s
CI for csaxs_bec / test (push) Successful in 1m46s
xrayeye_rotation_center_calibration_isolated/smear_experimental() reproducibly
crashed with "RuntimeError: GUI is not alive" when keep_shutter_open=True, right
after a long blocking device move (interferometer feedback reset, live rotation
sweep). Root cause: bec_widgets' GUI liveness check is a Redis heartbeat with a
10s TTL refreshed from the same Qt event loop that renders live-view frames;
with live view left on continuously, a long blocking move can starve that
heartbeat past its TTL even though the GUI process is still alive. Add
_gui_call_with_retry() and use it at the on_live_view_enabled(True) call sites
that follow these blocking waits, so the transient false negative is retried
instead of crashing the calibration.

Also reorder the sample-name prompt in find_rotation_center() and
find_rotation_center_smear_experimental() to run before the alignment GUI is
shown -- showing the GUI first steals OS focus, forcing the operator to click
back to the terminal to answer the prompt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-30 16:01:10 +02:00
x01dcandClaude Sonnet 5 fa322bfd43 fix(lamni): allow entering 0 to disable circular FOV in Tomo Params GUI
CI for csaxs_bec / test (pull_request) Successful in 1m50s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 1m51s
The scan already treats fov_circular==0 as "disabled" and defaults to
it, but the GUI spinbox floor of 0.1 made 0 unreachable. Lower the
floor to 0.0 and label the field so the meaning is explicit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-30 15:28:48 +02:00
x01dcandClaude Sonnet 5 40cbb17746 docs(lamni): explain fov check axis mapping instead of FIXME
CI for csaxs_bec / test (push) Successful in 2m15s
The stage_x_rot/fovy and stage_y_rot/fovx comparisons look swapped,
but are correct: alpha bakes in a fixed ~90 deg mechanical offset
between the piezo axes and the angle=0 beam frame that fovx/fovy are
defined in, so stage_x_rot actually tracks the beam-frame y-extent.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-30 15:15:10 +02:00
x12saandClaude Sonnet 5 771ee01a57 feat: migrate optics-hutch SmarAct stages to MCS2, align cross-controller compat
CI for csaxs_bec / test (pull_request) Successful in 3m48s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 2m7s
- Switch xbpm2x/xbpm2y/polrot/poly/scinx in bl_optics_hutch.yaml from the
  legacy MCS1 controller to the new MCS2 controller (mcs2-00029056.psi.ch),
  re-enabling polrot/poly with corrected axis assignments from the updated
  wiring table to avoid colliding with xbpm2x/xbpm2y on the same channel.
- Remove mcs2_config_test.yaml now that MCS2 is live on real stages.
- Give Mcs2Controller.find_reference_mark an unused hold_time parameter so
  shared call sites (smaract.py, flomni.py, omny.py, lamni_optics_mixin.py)
  that pass MCS1-style (axis, direction, holdTime, autoZero) args work
  unchanged against MCS2 devices too.
- Rename smaract_show_all/mcs2_show_all to a common show_all on both
  controllers, and have each list describe() from every registered MCS1 and
  MCS2 controller instead of only its own type.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UfjGm8MQrhCV8VaC9Tf4qx
2026-07-30 12:04:10 +02:00
Mirko HollerandClaude Sonnet 5 a65ab6cbdd feat: add SmarAct MCS2 device driver
CI for csaxs_bec / test (push) Successful in 1m54s
Adds a new driver for the SmarAct MCS2 controller (MCS2-C-0008, 9 channels),
parallel to the existing MCS1 (SCU) implementation. Uses the MCS2's raw
ASCII/SCPI interface over TCP (port 55551), which differs from MCS1 in units
(picometers), message termination (\r\n), and error handling (a polled error
queue instead of inline echoes).

- csaxs_bec/devices/mcs2: Mcs2Controller/Mcs2Motor and errors
- csaxs_bec/devices/sim/sim_mcs2.py: simulated backend for testing
- tests/tests_devices/test_mcs2.py: unit tests + sim end-to-end test
- device_configs: commented example stage in bl_optics_hutch.yaml, and a
  standalone single-axis mcs2_config_test.yaml

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-29 17:42:15 +02:00
Mirko HollerandClaude Sonnet 5 53f246a8d3 fix: address v4 scan migration review findings for flomni/lamni/omny
CI for csaxs_bec / test (pull_request) Successful in 1m52s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 2m15s
- restore omny_fermat_scan scan_name (was broken by _v4 rename)
- restore missing settling delay after LamNI feedback_disable
- make LamNI drift-correction moves consistently concurrent
- use self.actions.set for flomni rtx/rtz moves
- cap flomni corridor_size (explicit and auto-estimated) at 3um

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-29 17:12:01 +02:00
wakonig_k b813b05bb1 chore: cleanup legacy scans
CI for csaxs_bec / test (pull_request) Successful in 1m48s
CI for csaxs_bec / test (push) Successful in 3m32s
2026-07-29 14:48:35 +02:00
appel_c f0f7a3249a refactor(falcon): Migrate falcon to ScanServer ScanInfo model 2026-07-29 14:48:35 +02:00
wakonig_k cd13e7ed9e feat: migrate to v4 scans 2026-07-29 14:48:35 +02:00
appel_c df92754024 fix: typo in eiger_1_5 config
CI for csaxs_bec / test (pull_request) Successful in 1m50s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 1m50s
2026-07-28 14:32:09 +02:00
appel_c f7dd245559 fix: add saxs_scan_macro 2026-07-28 14:32:09 +02:00
appel_c 8b0a95133c test: fix eiger on_stage test 2026-07-28 14:32:09 +02:00
appel_c e32c959480 fix: fix formatting eiger 2026-07-28 14:32:09 +02:00
x12sa 56297c7928 fix(eiger): fix eiger check for IDLE in on_stage 2026-07-28 14:32:09 +02:00
appel_c d1c45a9081 add azimintsettings 2026-07-28 14:32:09 +02:00
x12sa 5fd4025e89 changes from the beamline 2026-07-28 14:32:09 +02:00
x12sa a68c29c03c scanning SAXS, e23738 2026-07-28 14:32:09 +02:00
appel_c 71ad9fc12d fix(mcs): initialize _num_lines in init
CI for csaxs_bec / test (pull_request) Successful in 1m48s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 6s
CI for csaxs_bec / test (push) Successful in 1m55s
2026-07-28 13:48:30 +02:00
x01dc 2aca187c86 fix(LamNI): skip 22.5 deg approach rotation when shutter is closed
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 1m51s
The k=2..8 alignment steps always rotated via a halfway "approach"
angle before the 45 deg target, to let the operator watch the sample
sweep through in live view. That's only useful when keep_shutter_open
is True; with the shutter closed nobody sees the intermediate move, so
just rotate straight to the target angle in that case.

Also bump the OMNY/FlOMNI post-fshopen() freeze-frame delay in
update_frame() from 0.5s to 1s to match LamNI's, for consistent
behavior between the two plugins.
2026-07-28 13:35:05 +02:00
x01dcandClaude Sonnet 5 89b185eae2 fix(deps): make pygobject an optional extra, not a hard dependency
CI for csaxs_bec / test (pull_request) Successful in 1m47s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 1m51s
pygobject ships no PyPI wheels, so pip install always compiles it from
source, which requires the OS gobject-introspection dev package at
install time. As a mandatory dependency this broke plain `pip install
csaxs_bec` on CI and on Read the Docs, neither of which has that
package installed. Move it to the `allied_vision` extra so only hosts
that actually run the camera (which already need Aravis + the OS
package present) opt in via `pip install csaxs_bec[allied_vision]`.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-28 13:25:25 +02:00
x01dc 27a40518af fix(LamNI): revert xray eye IDS camera to default 5 Hz poll rate
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 1m51s
The live_mode_poll_interval_s: 0.02 override (50 Hz) made the GUI
unusably laggy. Remove it so cam_xeye falls back to the class
default of 0.2 s (5 Hz).
2026-07-28 13:23:37 +02:00
x01dc 107981f392 fix(devices): remove deprecated XOMNYI-XEYE-ACQ:0 EPICS PV writes
CI for csaxs_bec / test (pull_request) Successful in 1m52s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 1s
CI for csaxs_bec / test (push) Successful in 1m49s
This PV belonged to the old EPICS/LabView X-ray-eye acquisition system
that both LamNI and OMNY alignment have already replaced with the
BEC-native cam_xeye (IDSCamera) device and GUI-driven workflow. The PV
no longer has a listener, so the write only produced a "cannot connect"
warning at the start of LamNI's tomo_alignment_scan() (via leye_out())
and OMNY's oeye_out() -- remove both, plus the now-dead epics_put
imports left behind in lamni_optics_mixin.py, omny_optics_mixin.py, and
flomni_optics_mixin.py, and a leftover print() in flomni's
x_ray_eye_align.py that referenced the same PV without ever writing it.
2026-07-28 12:16:41 +02:00
x01dcandClaude Sonnet 5 654f8be4eb feat(devices): add FZP details user parameter to optics stages
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 1m55s
Adds a free-text "fzp_details" userParameter (default "manufacturing
notes here") to the loptx/foptx/ofzpx optics-stage devices for LamNI,
flomni and OMNY, alongside the existing fzp_diameter/
fzp_outermost_zone_width parameters, and prints it in each beamline's
tomography-start PDF report.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-28 11:54:15 +02:00
x01dcandClaude Sonnet 5 89c5ed1c9e fix(LamNI): don't auto-retry lsamrot moves aborted by stop()
CI for csaxs_bec / test (pull_request) Successful in 1m50s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 2s
CI for csaxs_bec / test (push) Successful in 1m57s
move_and_finish()'s spurious-trip retry (added in 1f85106) couldn't tell a
genuine Galil safety-thread trip apart from a user/scan-initiated stop()
(e.g. Ctrl+C): an aborted move looked like an incomplete move either way,
so the abort got silently undone by resetting the error latches and
re-issuing the original move to the same target.

Track stop() requests on a per-motor threading.Event, cleared at the start
of each move() and checked (twice, since reset_axis_errors() itself takes
a few round-trips) before the retry branch fires, so an aborted move is
now reported as a failure instead of being retried.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-28 11:37:23 +02:00
x01dc c42595922d fix(devices): defer Aravis import-guard from Camera.__init__ to on_connect()
CI for csaxs_bec / test (pull_request) Successful in 1m59s
Read the Docs Deploy Trigger / trigger-rtd-webhook (push) Successful in 3s
CI for csaxs_bec / test (push) Successful in 2m0s
Camera.__init__ raised ImportError unconditionally whenever the Aravis
GObject-Introspection library wasn't importable, even with connect=False --
contradicting the module's own "lazy initialization" docstring and
breaking every unit test in CI, since Aravis is a system library (not
pip-installable) that CI never has installed. The test fixture builds a
real AlliedVisionAravisCamera(connect=False) and only mocks camera.cam
afterward, so the raise fired before mocking ever got a chance to run.

Move the guard into on_connect(), mirroring IDSCamera's working pattern
(its equivalent check lives in the object only built by on_connect(),
never at construction time). Construction is now independent of whether
Aravis is installed; on_connect() still raises the same clear error the
moment something actually tries to talk to hardware.
2026-07-28 10:46:50 +02:00
x01dc 2bd161cd63 config(devices): drop allied_vision_test.yaml, add commented example to ptycho_omny
allied_vision_test.yaml was only ever a scratch config for exercising the
camera during bring-up; the same commented allied_vision_cam example
already lives in bl_detectors.yaml, so keep that one and add the matching
commented block to ptycho_omny.yaml instead of a separate file.
2026-07-28 10:46:41 +02:00