Follow-ups to the Idle-vs-Error acquisition failure split:
- JFJochServices::Stop: raise the critical detector fault BEFORE the ordinary
receiver/writer exception. Both can be set at once (detector not idle, then
receiver->Stop() also throws); throwing the ordinary one first masked the
detector fault and returned the broker to Idle instead of Error, skipping the
required re-initialisation.
- SLSDetectorWrapper::Stop/Deactivate: rethrow a JFJochException as-is (as Start
already does) so InternalStop's JFJochCriticalException is not downgraded to an
ordinary JFJochException by the generic catch.
- JFJochServices::Start: wrap the whole best-effort receiver cleanup (Cancel +
Stop) in the catch so a throwing Cancel cannot replace the original detector
exception before it is re-raised.
Also fix the "cannot create indexing pool" failure seen when retrying
initialize after a failed acquisition start: a failed start leaves the receiver
(and its GPU resources) alive until the next Start, but the retried initialize
rebuilds the indexer pool first, so the fresh GPU indexer had to coexist with
the stale receiver and its init failed. JFJochReceiverService::Indexing now
releases the previous receiver before (re)building the pool (safe: only runs
when the receiver is idle), which also removes a dangling pool pointer held by
that receiver.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Going to the Error state after any acquisition failure forced an expensive
re-initialisation (reconnect + full detector config + pedestals), even when the
detector was still perfectly configured and only a transient problem occurred.
Split failures into two classes:
- ordinary acquisition failures (receiver/writer/analysis problems, missed
packets, writer disconnect) return to Idle with an Error-severity message, so
the run can be retried without re-initialising;
- failures that leave the detector in an undefined state throw the new
JFJochCriticalException and still go to Error, forcing re-initialisation.
The detector layer is the single source of truth for "detector faulted":
SLSDetectorWrapper::InternalStop and DectrisDetectorWrapper::CheckBusyOrError
raise JFJochCriticalException on the ERROR state, and JFJochServices::Stop raises
it when the detector does not return to idle at the end of a run. MeasurementThread
dispatches purely on exception type - no detector-status field checks.
Also:
- JFJochServices::Start now stops the receiver it launched if the detector fails
to start, so the service returns to idle cleanly and the run can be retried.
- A synchronous Start rethrows the failure to the caller (HTTP layer) via a
stored exception_ptr, so a failed start is no longer reported as HTTP 200.
- JFJochServices::Stop no longer throws on a writer error; it is reported through
receiver_output.writer_err and surfaced as an Idle + Error-severity message,
which makes the previously-dead writer_err branch in MeasurementThread live.
Initialisation, calibration/pedestal, SelectDetector and Deactivate keep the
Error-state behaviour, as those genuinely leave the system in an undefined state.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This is an UNSTABLE release. It includes many experimental features, as well as many AI generated fixes. We recommend using rc.152 for production use.
* jfjoch_broker: Add EXPERIMENTAL pixelrefine mode for image processing
* jfjoch_broker: Allow to load user mask from 8-bit and 16-bit TIFF files
* jfjoch_broker: Add ROI calculation in non-FPGA workflow
* jfjoch_broker: Fixes to TCP image pusher
* jfjoch_broker: Remove NUMA bindings
* jfjoch_broker: Improvements to indexing
* jfjoch_broker: For PSI EIGER, trimming energies are taken from the detector configuration (now compulsory) instead of hardcoded values
* jfjoch_writer: Save ROI definitions and the per-pixel ROI bitmap in the master file; azimuthal ROIs support phi (angular) sectors
* jfjoch_viewer: Major redesign with dockable panels and saved layouts, plus on-canvas creation/move/resize of box, circle and azimuthal ROIs
* jfjoch_viewer: Run jfjoch_process reprocessing jobs from inside the GUI and overlay per-run results
Reviewed-on: #63
* jfjoch_broker: For PSI EIGER detector allow to disable individual half-modules by putting empty hostname
Reviewed-on: #61
Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch>
Co-committed-by: Filip Leonarski <filip.leonarski@psi.ch>
This is an UNSTABLE release. The release has significant modifications and bug fixes, if things go wrong, it is better to revert to 1.0.0-rc.132.
* jfjoch_broker: Further reduce startup time for DECTRIS detectors by selectively modifying SIMPLON parameters on `/start`
* jfjoch_broker: Further reduce startup time for DECTRIS detectors by not setting beam center and detector distance via SIMPLON API on '/start'
* jfjoch_broker: Add an extra message to ZeroMQ puller ready to monitor Lite worklow preparation time
* jfjoch_broker: Image buffer configuration is postponed for Lite receiver flow till start message is received
* jfjoch_broker: Use nanoseconds internally for frame/image/readout time
* jfjoch_broker: Extra messages added for receiver operation (to be removed after debugging finished)
* jfojch_broker: Improve profiling of different data analysis steps
* jfjoch_broker: Record integration reflection count
* jfjoch_broker: Fix bug where ZeroMQ preview frequency was confusing time units (micro vs. milliseconds)
* jfjoch_broker: Fix bug where '/wait_till_done' got deadlocked
* jfjoch_writer: Fix confusion between NaN and zero in floating-point datasets
**Breaking changes**: detector definition is now using nanoseconds to define minimum frame time, minimum count time and readout time.
Reviewed-on: #49
This is an UNSTABLE release.
* jfjoch_viewer: Add keyboard shortcuts and option to copy image to clipboard
* jfjoch_broker: Fix bit-width and exposure time for PSI EIGER detectors
Reviewed-on: #15
Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch>
Co-committed-by: Filip Leonarski <filip.leonarski@psi.ch>