Feat/trigger timing consistency #310
Merged
menzel
merged 5 commits from 2026-09-08 14:25:55 +02:00
feat/trigger-timing-consistency into main
No Reviewers
Labels
Clear labels
issue::not confirmed
issue::not reproducible
issue::reproducible
priority::critical
priority::needed
priority::nice to have
scope::backend
scope::frontend
stage::in development
stage::on hold
stage::pre_release
stage::ready for review
stage::selected for development
stage::weekly backlog
type::bug
type::discussion
type::doc
type::feature
type::improvement
type::test
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
Used if an issue has not yet been confirmed by a developer
Used if an issue is not reproducible
Used if a developer was able to reproduce the issue
Should be done as soon as possible
An important update to the code base
Not really needed but a good improvement
An issue regarding the backend services
An issue regarding the user-facing services
This issue is currently being worked on
Something is blocking the development
For issues that have been merged into a pre-release branch and are waiting for their release.
For issues that have been resolved and are ready for review
This issue has been selected for development but has not been scheduled yet
This issue has been selected for development for the next development cycle
It's a bug!
A discussion is wanted/needed
Improvements to the documentation
A new feature
Neither a feature nor a bug but an improvement to the code base
Missing tests or improvements to the test suite
Something is not working
This issue or pull request already exists
New feature
Need some help
Something is wrong
More information is needed
This won't be fixed
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
Assignees
acerbo_a (acerbo_a)
bec-gitea
chen_h2 (chen_h2)
debenjak_l (debenjak_l)
diaz (diaz)
divall_e (divall_e)
guizar_m (guizar_m)
haghta_s (haghta_s)
holler (holler)
lombosi_c (lombosi_c)
malu_s (malu_s)
menzel (menzel)
perl_d (perl_d)
usov_i (usov_i)
wakonig_k (wakonig_k)
wang_x1 (wang_x1)
wyzula_j (wyzula_j)
zamofing_t (zamofing_t)
zhang_y7 (zhang_y7)
Clear assignees
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: bec/csaxs_bec#310
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
exp_time is the trigger period, not the exposure. DDG2 gated for exp_time − readout_time but the Eiger was sent the full exp_time as image_time_us, so it integrated ~180 µs past the falling edge of its own gate — 172.8 µs overhang measured on a scope. Four independent notions of "readout time" are now one: DDG2 derives the gap from the scan's readout_time floored by its configured value and exposes effective_readout_times(); the Eiger subtracts the same number. MIN_EXP_TIME is split out so validation behaviour is unchanged.
64c2fffalso fixes a deviceConfig override that never worked — readout_time wasn't a named parameter of the subclasses, so the device server silently dropped it (same trap as prefix); a test now pins the signatures.Both devices log their exposure window at on_stage; the test is that the Eiger's acquisition equals DDG2's pulse width.
Behaviour change: scans that don't set readout_time deliver 200 µs less exposure (0.5 % at 40 ms) — matters for anyone normalising against pre-2026-09-03 data.
Deployed at cSAXS on 2026-09-03 as 011d403/f450f29/934d8d2 and in production since; timing has been tested extensively at the beamline with no remaining inconsistencies found. Adds 26 tests; merged into current main: 101 failed / 509 passed / 15 skipped against a baseline of 101 failed / 483 passed (the 101 are pre-existing motor-controller failures from a local ophyd_devices skew).
scan_info's exp_time is the trigger PERIOD. DDG2 gates for exp_time minus a readout time, but the Eiger was sent the full exp_time as image_time_us, so the detector acquired 180 us past the falling edge of its own gate and finished only 20 us before the next trigger -- that 20 us being JungfrauJoch's internal board-readout allowance, and the entire margin available. Measured on a scope as a 172.8 us overhang. Four independent notions of "readout time" existed: 500 us EIGER*_READOUT_TIME_US validation floor only, no effect on anything 200 us DDG2 DEFAULT_READOUT_TIMES["ab"] sets the gate width 20 us JungfrauJoch deployment config applied internally by JFJoch - scan parameter readout_time honoured by the Falcon, ignored by DDG2 They are now one. DDG2 derives the gap from the scan's readout_time, floored by its configured value (scans default it to 0), and exposes effective_readout_times(). The Eiger subtracts the same number from image_time_us. The Falcon already used the scan value, so it needs no change. The Eiger's 500 us constant is split in two, because it was doing two jobs: a MIN_EXP_TIME validation floor keeps today's behaviour exactly, while the new EIGER_READOUT_TIME defaults to 2e-4 to match the delay generator. The _US suffix on constants holding seconds is dropped in all three modules. Both devices log the effective exposure window at on_stage, so a period/exposure mismatch is visible in the logs rather than only on an oscilloscope. NOTE: this shortens the delivered exposure by the readout time -- 200 us, i.e. 0.5% at 40 ms -- for scans that do not set readout_time. Users should be told before this is deployed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KLnmUurqcNd1FiDY5M2uZr