- tomo_scan type 1 with zero_deg_reference_at_each_subtomo: no extra reference before sub-tomogram 1
of a new scan (fixed 0-deg shot + sub-tomogram 1's first projection = 2 in a row, was 3)
- tomo_scan: a declined eye/optics or filter gate raises FlomniError instead of returning (the tomo
queue marked the job "done" without data)
- feye_out / feye_in: "no" (direct beam still visible, fttrx1 missing) raises FlomniOpticsError instead
of returning (tomo_alignment_scan measured on with the eye in)
- tweak_cursor and laser_parameters_tweak_tracking: read_escape_suffix() waits briefly for a split
arrow-key sequence and ignores ESC alone (read(2) unpacking raised); tweak_cursor message names the device
- tomo_parameters_cli: angle range re-asked until 180 or 360; _get_val re-asks on a non-number
- check_position_is_valid message 0-20; collect_empty_frames docstring: the sample is moved out
- omny/AI_docs/TODO_flomni_review_2026-10_findings.md: the same bugs in OMNY (x-ray eye Ctrl-C, special angles)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019aWcwG89wi7oVyrefukXX6
- start_x_ray_eye_alignment: _get_user_param_safe() needs the device name (dev[name]); with dev.fsamx the
KeyboardInterrupt handler raised KeyError and fsamx was never returned to its in position
- ffzp_info: the OSA collides at fosaz = 33 - foptz (compute_osa_remaining_space), printed 33 - fosaz
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019aWcwG89wi7oVyrefukXX6
- np.isclose(a, b, x) took x as rtol: fsamx out (+-1.6 mm), gripper sensor voltage (+-0.55 V / +-1.1 V at
-2.2 V), fsamx in checks now use atol (0.2 / 0.5 mm, 0.25 / 0.5 V, fsamx out 0.5 mm = Galil tolerance)
- tomo_alignment_scan: an angle with a TimeoutError is repeated (successful was set unconditionally, the
angle was skipped); ptychotomoalign_scannum.txt is rewritten with the accepted scans if numbers shifted
- special angles: special_angle_tolerance is used (was hard-coded 0.5; init value 20 -> 0.5), any remaining
special angle matches (not only the first in the list), kept on tomo_scan_resume in the same session
- tomo_scan_resume after a completed scan does nothing (progress tomo_completed; re-acquired the last
projection and repeated the end-of-scan steps before); tomo_queue_reacquire clears the flag
- laser_parameters_tweak_tracking docstring: step 0.02
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019aWcwG89wi7oVyrefukXX6
Mirko 2026-10-23: a user could change the loop settings and even save them as the new default. The user guide now
only says that the real-time loop settings are set by the local contact, that every scan stores them, and where the
details are; the commands (realtime_system, trigger, tracker), the profiles, save_as_default, the baseline device,
the connection and the web HMI are in plugins/flomni/docs/local_contact_only-realtime_system.md. The detector
trigger section of the user guide keeps the explanation and the measured times, without commands. show() / help()
name the document.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019aWcwG89wi7oVyrefukXX6
- help("<setting>"): what it does (help text of the flOMNI definition, as the web HMI tooltips), range, live and
saved value, the loop parameters it sets, its rules; help("all"): every setting by group
- realtime_system is for beamline scientists / local contact only (Mirko 2026-10-23): module docstring, a line at
show() / help(), user guide section heading and note
- tests: help output
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019aWcwG89wi7oVyrefukXX6
Mirko 2026-10-23: the token goes into the device config (behind the beamline firewall like the other devices); the
user commands call the BEC device in the background.
- FlomniLoopSettings: api_get / api_post (RPC for flomni.realtime_system; only /api/settings* and /api/status;
10 s timeout, no back-off). Not named set / put: the BEC device server treats those as ophyd writes (refused on
a readOnly device; checked in bec_server rpc_handler.py)
- FlomniRealtimeSystem: requests through dev.flomni_loop_settings when it exists and is enabled (errors from the
device -> RealtimeSystemError), else direct HTTP as before; show() names the route
- ptycho_flomni.yaml: token field (empty: token_file is used)
- tests: RPC methods and path check; routing through a device and back to direct HTTP when it is disabled
(checked against bec_server: deviceConfig keys are matched to the constructor parameters, device_manager is
passed, the constructor does no network access)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019aWcwG89wi7oVyrefukXX6
Decisions Mirko 2026-10-23: settings only (not all loop parameters), snapshot at the scan start, web HMI down ->
marked unavailable and the scan continues, flOMNI only for now, token part of the device configuration.
- devices/omny/flomni_loop_settings.py (new): FlomniLoopSettings, readoutPriority baseline (the Fermat scan reads
the baseline devices in prepare_scan): one signal per setting (21, NaN when not available), available, message,
unsaved / inconsistent counts, violated error rules, definition path + sha1, compact snapshot_json; never
raises; after a failure no new attempt for 60 s (a tomogram does not wait for the timeout at every projection);
show() / snapshot() for the user
- devices/omny/webhmi_client.py (new): the HTTP client (URL with port-80 fallback, token value or file, errors)
shared by the device and flomni.realtime_system (which now uses it; behaviour unchanged)
- ptycho_flomni.yaml: flomni_loop_settings with token_file (the token value only in a config that is not
committed), host mpc2844.psi.ch, timeout 2 s
- tests: tests_devices/test_flomni_loop_settings.py (stub web HMI: values, counts, unavailable / back-off,
unreachable, token file); checked end-to-end against the web HMI with the flOMNI definition and fakecore (all
21 settings filled)
- user guide: the settings are stored with every scan
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019aWcwG89wi7oVyrefukXX6
- the former flomni.interferometer_trigger_* aliases are removed (Mirko 2026-10-23); user guide updated
- flomni.realtime_system: when the default URL http://<rtx host>:8080 is not reachable, the request goes to port
80 of the same host (nftables redirect to the web HMI on the loop machine) and that URL is kept; an explicit URL
(argument or FLOMNI_WEBHMI_URL) gets no fallback; test added
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019aWcwG89wi7oVyrefukXX6
- user guide: detector-trigger commands under flomni.realtime_system.trigger_* (old names still work), new section
"Real-time loop settings (expert)"
- calibration how-to: steps 1-3 as profiles fzp_off / fzp_calibration / production (+ fast_scan); trigger values are
OnTargetTrigger parameters; move-beyond sizing with the loop-settings rule (0.6 x stroke - Abbe limit)
- range how-to: FZP range through the loop settings (Ub / Lb and Feedforward limits together)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019aWcwG89wi7oVyrefukXX6
The ConstEmitter is no longer in the flOMNI loop (flOMNI 773df74, branch fzp-move-beyond): its values are module
parameters, set with their rules by the web HMI on mpc2844 (RT-system webhmi/loopsettings.py, REST /api/settings).
- flomni_realtime_system.py (new): FlomniRealtimeSystem, flomni.realtime_system: show / get / check / set
(refused with the reason, adjust=True for the dependent settings) / profiles / apply_profile / unsaved /
save_as_default, shortcuts trigger_* and tracking_targets; stdlib HTTP, API token from ~/.flomni_webhmi_token
(FLOMNI_WEBHMI_TOKEN_FILE), URL http://<rtx host>:8080 (FLOMNI_WEBHMI_URL). No logic of its own: the same rules
as the web page.
- flomni.py: flomni.realtime_system; laser_parameters_* and laser_parameters_tweak_tracking() through it;
interferometer_trigger_* are aliases of realtime_system.trigger_* (renamed, Mirko: "interferometer" was
confusing next to flomni.laser_*)
- rt_flomni_ophyd.py: emitter_* methods and their USER_ACCESS entries removed (the e-commands now answer with an
error line); move_xyz stays
- tests: test_flomni_realtime_system.py against a small local HTTP server standing in for the web HMI
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019aWcwG89wi7oVyrefukXX6
Markdown versions of local_contact_only-howto_calibrate_the_fzp_scanner.pdf and
local_contact_only-howto_limit_the_fzp_scanner_range.pdf (original text kept, update sections for the present
flOMNI loop). New section "Move-beyond" (FAST_FZP_PID_LOOP(0) < 0 of the sample PIDs): mechanism, sizing (about
half the FZP stroke), Abbe correction on the FZP side, hold (5) now reads the FZP drive incl. feedforward
(flomni repo, branch fzp-move-beyond, 6a15f68). The PDFs are kept.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019aWcwG89wi7oVyrefukXX6