Commit Graph
1034 Commits
Author SHA1 Message Date
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_candwakonig_k 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
x12saandappel_c 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
x12saandappel_c 5fd4025e89 changes from the beamline 2026-07-28 14:32:09 +02:00
x12saandappel_c 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
x01dcandholler 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
x01dcandholler 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
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
x01dc 285691b629 feat(devices): add live-mode FPS measurement to AlliedVisionAravisCamera
CI for csaxs_bec / test (push) Failing after 1m42s
CI for csaxs_bec / test (pull_request) Failing after 1m38s
Port get_live_fps()/live_mode_poll_interval_s from IDSCamera (added on
main): a rolling deque of the last 10 live-mode push timestamps, exposed
as a measured frame rate rather than assuming the nominal poll interval
is actually achieved -- verified against real hardware, where the
Alvium G1-507m's actual acquisition/readout time brings the achievable
rate to ~3 fps despite the 0.2s (5 Hz) nominal poll interval.

Mirrors the same three unit tests added for IDSCamera's version.
2026-07-28 10:26:40 +02:00
x01dc 13326c0985 Merge remote-tracking branch 'origin/main' into feat/allied_vision
# Conflicts:
#	csaxs_bec/device_configs/bl_detectors.yaml
2026-07-28 10:17:04 +02:00
x01dc a96d24a3cc fix(devices): use real camera_id, disable auto live-mode, pin pygobject
Update the placeholder camera_id in allied_vision_test.yaml/bl_detectors.yaml
to the Aravis device ID discovered on the actual Alvium G1-507m hardware,
and set live_mode back to False (explicit, not deleted) so the camera stays
idle until start_live_mode() is called -- matching every real IDS camera
config, instead of auto-starting its live-mode polling thread as soon as
the device connects.

Pin pygobject<3.52 in pyproject.toml: 3.52+ requires girepository-2.0
(GLib >=2.80/gobject-introspection >=1.80), which this RHEL9 host's system
packages don't provide (only the older girepository-1.0 via
gobject-introspection 1.68) -- unpinned pip install fails at build time.
Document both the camera_id lookup and the pin in the README.
2026-07-28 10:16:18 +02:00
x01dc 13e9cb21e4 fix(LamNI): update tests for prompts/kwargs added earlier this branch
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 1m59s
Several tomo_scan()/tomo_alignment_scan()/find_rotation_center() tests
started failing (CI) after recent commits on this branch introduced new
input()-backed confirmation/sample-name prompts, an
alignment_scan_progress GUI proxy, and tomo_queue_execute()'s
interactive=False kwarg -- none of which the existing test fixtures or
assertions were updated for. Mock/bypass the new prompts and GUI calls,
add the missing _alignment_scan_progress_proxy to the bare-object test
fixture, and update two assertions (tomo_queue interactive kwarg,
account-less sample registration) to match the intended new behavior.
2026-07-28 09:53:59 +02:00
x01dc 56467682a9 config(LamNI,flomni): add FZP params to the simulated device configs too
CI for csaxs_bec / test (push) Failing after 4m6s
CI for csaxs_bec / test (pull_request) Failing after 2m3s
simulated_lamni.yaml/simulated_flomni.yaml define their own separate
loptx/foptx (not shared with ptycho_lamni.yaml/ptycho_flomni.yaml) --
missed these when adding fzp_diameter/fzp_outermost_zone_width/
detector_distance earlier, so a simulated-only session wouldn't have
had them. Same values (170 micron, 60 nm, -1).
2026-07-27 17:49:05 +02:00
x01dc 79f257f072 feat(LamNI,flomni): add PSI logo to every PDF report page footer
Downloaded from https://intranet.psi.ch/themes/custom/design/logo.svg
(no gradients/filters/embedded fonts -- confirmed fpdf2 renders it
directly, no PNG conversion needed) and stored as psi_logo.svg in
OMNY_shared. Added TomoQueueMixin._add_psi_footer(), which overrides
the fpdf instance's footer() callback (PDFWriter/BECPDF live in
bec_lib, a separate repo with no public API for this) so the logo
repeats on every page -- unlike the header logo, which is drawn once
inline, a report can span multiple pages (e.g. a long
at_each_angle_hook source dump). Also drops the microseconds from the
existing "BEC, <timestamp>" footer text while reimplementing it, per
request ("ms precision is not needed"). Verified end-to-end with
bec_lib's real PDFWriter: a 300-line hook source forced a 7-page
report, with the logo correctly repeating on every page.
2026-07-27 17:48:57 +02:00
x01dc 6c06b63ece fix(LamNI,flomni): FZP diameter/zone-width wrongly blanked to N/A
fzp_diameter_um/fzp_zone_width_nm were read inside the same try block
as the focal-distance calculation, which also needs energy_kev. When
the photon energy read fails (as it does in at least one simulated
session -- confirmed live: dev.ccm_energy unavailable), the exception
wiped out the diameter/zone-width display too, even though those come
from config (loptx/foptx userParameter) and were read just fine.
Split into two independent try blocks: diameter/zone-width no longer
depend on a working energy read, only the focal distance itself does.
2026-07-27 17:48:26 +02:00
x01dc 1b6b6a41a1 feat(LamNI,flomni): add FZP optics info to the PDF report
Adds FZP diameter, outermost zone width, focal distance,
focus-to-sample distance, and sample-to-detector distance to
write_pdf_report(). Diameter/zone-width/detector-distance come from
the userParameter entries just added to loptx/foptx; focal distance
is computed with the same formula lfzp_info()/ffzp_info() already use
(diameter * zone_width / wavelength); focus-to-sample distance reuses
their existing live z-stage-based calculation rather than storing a
separate value. Replaces this exact old SPEC workflow
(_tomo_other_parameters interactively asking for these same numbers
every time) with values read automatically from config + live
hardware.

Also fixes FlOMNI's "Current photon energy: To be implemented"
placeholder (never wired up) -- needed a real value for the new focal
distance calculation anyway, and dev.ccm_energy is the same device
ffzp_info() already reads.
2026-07-27 17:43:53 +02:00
x01dc e7df1209d1 fix(LamNI): lfzp_info() printed focal distance in meters labeled as mm
focal_distance was computed in meters (consistent with the rest of the
function, e.g. beam_size's own internal *1000 conversions), but the
table row printed it directly as "X.XX mm" with no conversion -- off
by 1000x (e.g. showing "0.05 mm" instead of "51.34 mm"). FlOMNI's and
OMNY's equivalent ffzp_info()/ofzp_info() already convert correctly;
fix just the display here to match, without touching the
meters-based internal variable beam_size still depends on.
2026-07-27 17:35:33 +02:00
x01dc 8b3a65606c config(LamNI,flomni): add FZP diameter/zone-width/detector-distance params
Adds fzp_diameter (170 micron), fzp_outermost_zone_width (60 nm), and
detector_distance (-1, unknown for now) as userParameter entries on
loptx/foptx. LamNI's values match FlOMNI's already-documented active
FZP (per its "#170 micron, 60 nm" comment) -- confirmed with the user
that LamNI currently uses the same optic. Feeds the new PDF report
fields in the next commit.
2026-07-27 17:35:10 +02:00
x01dc 6954fbb7f4 refactor(OMNY): move omny_general_tools.py into OMNY_shared
CI for csaxs_bec / test (push) Failing after 2m27s
OMNYTools, PtychoReconstructor, and TomoIDManager were sitting under
the omny plugin's own directory, but are imported by LamNI, FlOMNI,
and cSAXS too -- none of the three classes reference anything
OMNY-specific (device names are always passed in as parameters).
OMNY_shared already exists for exactly this kind of cross-setup code
(tomo_queue_mixin.py, web_common.py, webpage_generator_base.py), so
move it there and update all five import sites. Pure relocation, no
behavior change.
2026-07-27 17:19:22 +02:00
x01dc 97ea67b01a fix(flomni): use the real setup logo in the PDF report, fix column gaps
CI for csaxs_bec / test (push) Failing after 11m52s
Mirrors LamNI.write_pdf_report()'s same fix: replace the ASCII-art
header with the actual flOMNI.png logo (already correctly resolved
for the scilog attachment, just never used in the PDF itself),
embedded via PDFWriter's underlying fpdf object. Also left-justify
values instead of right-justifying them in a wide fixed field, to
remove the big ragged gap after short labels. Drops a leftover debug
print(logo_file).
2026-07-27 17:13:57 +02:00
x01dc f8ced692d3 fix(LamNI): use the real setup logo in the PDF report, fix column gaps
Replace the ASCII-art header with the actual LamNI.png logo, embedded
via PDFWriter's underlying fpdf object (bec_lib's PDFWriter has no
public image API). Also fix the label/value formatting: values were
right-justified in a wide fixed field, leaving a big ragged gap after
short labels -- left-justify both instead for a clean, tight
"label: value" layout.

Also fixes a real bug found along the way: the scilog attachment
referenced "LamNI_logo.png", a file that has never existed (the actual
file is LamNI.png) -- the resulting FileNotFoundError was swallowed by
write_pdf_report()'s generic try/except, so the scilog message has
been silently failing to send every time. Now uses the one correct,
shared logo_path for both the PDF and the scilog attachment.
2026-07-27 17:13:49 +02:00
x01dc eb61df1c93 fix(OMNY): use requests instead of shelling out to wget for tomo ID
CI for csaxs_bec / test (push) Failing after 11m43s
TomoIDManager.register() called wget via subprocess with shell=True,
interpolating sample_name/eaccount/etc. unescaped into the command
string -- broke outright wherever wget isn't installed (as hit while
testing: "wget: command not found", silently falling back to tomo ID
0), and was a latent shell-injection risk. Use requests.get() with a
params dict instead: no external binary dependency, proper URL
encoding, and the same self-signed-cert/SSRF handling already used by
the samples PDF upload. Drops the now-unused OMNYToolsError class and
TMP_FILE/subprocess, which only existed to support the wget call.
2026-07-27 17:06:10 +02:00
x01dc 3422eedcc1 fix(OMNY): call tomo_scan(interactive=False) from tomo_queue_execute()
CI for csaxs_bec / test (push) Failing after 5m0s
Wires the queue-safe fine-alignment warning (previous LamNI/Flomni
commits) into the actual queue dispatch path.
2026-07-27 17:02:17 +02:00
x01dc d97692e090 fix(flomni): always attempt tomo_id registration, accept interactive kwarg
Mirrors LamNI.tomo_scan()'s same fix: remove the outer
"bec.active_account != ''" short-circuit so an empty/test account still
goes through add_sample_database() -> TomoIDManager.register() (which
now handles test-host registration itself) instead of hard-coding
tomo_id=0. Also accept an unused interactive kwarg for signature
compatibility with LamNI.tomo_scan(), since tomo_queue_execute() (shared
between both setups) calls tomo_scan(interactive=False) uniformly.
2026-07-27 17:02:05 +02:00
x01dc 1159b018f0 fix(LamNI): don't block the tomo queue on the fine-alignment check
tomo_queue_execute() runs queued scans unattended, potentially for
hours -- tomo_scan()'s fine-alignment prompt would block forever there
with nobody watching. Add interactive: bool = True; when False (queue
use), the check no longer prompts or aborts -- it prints a bold red
warning, waits 10s, and always proceeds.

Also remove the outer "bec.active_account != ''" short-circuit that
hard-coded tomo_id=0 for an empty account without even attempting
registration -- always call add_sample_database() now and let
TomoIDManager.register() (test-host registration, previous commit)
decide the right outcome instead of pre-empting it here.
2026-07-27 17:01:52 +02:00
x01dc 64f5a57fa1 feat(OMNY): add OMNYTools.printredbold()
Mirrors the existing printgreenbold() -- needed for the tomo_scan()
unattended-queue warning (bold red instead of bold green).
2026-07-27 17:01:31 +02:00
x01dc fe47059f88 fix(OMNY): skip PDF upload without a real tomo_id, widen error logging
tomo_id == FALLBACK_TOMO_ID (0) means add_sample_database() never
actually registered a measurement server-side, so there's no reserved
"new.pdf" slot -- uploading anyway would silently claim whatever
number countersaver.txt currently holds, i.e. an unrelated real
measurement's slot. Skip with a clear message instead. Also widen the
truncated response text in the upload warning/log messages (120 -> 400
chars), which had cut off the file+line a real PHP error would show,
making a live parse-error response undiagnosable from the client log
alone (as happened while testing this).
2026-07-27 16:58:43 +02:00