The merge-analysis window gets a fourth view beside the plot, the table and the ISa diagnostic: the rugnux result report, the same text the command line writes as <prefix>_report.txt, in a fixed-width read-only page. The viewer's in-process run never wrote that file, so the controller renders it from the run's own results right after the pipeline finishes and hands it along with the finished signal; as with WriteResultReport, a report failure leaves the report empty rather than losing the run. The view buttons now map to page widgets instead of stack indices, so an absent page (no ISa scatter, no report) cannot shift the pages behind it. The calibration result window already opens itself when a calibration job finishes (rc-161); verified against a LaB6 dataset, unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015vRwzF8PLaaa2novAKYorq
73 lines
2.8 KiB
C++
73 lines
2.8 KiB
C++
// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
#pragma once
|
|
|
|
#include <QObject>
|
|
#include <QString>
|
|
|
|
#include <atomic>
|
|
#include <chrono>
|
|
#include <memory>
|
|
#include <mutex>
|
|
#include <thread>
|
|
|
|
#include "../rugnux/Rugnux.h"
|
|
#include "../common/DiffractionExperiment.h"
|
|
#include "../common/PixelMask.h"
|
|
#include "../reader/JFJochReaderDataset.h"
|
|
|
|
Q_DECLARE_METATYPE(ProcessResult)
|
|
|
|
// Runs one Rugnux job off the GUI thread and reports back via queued Qt signals. The job
|
|
// opens its own private reader on the file (HDF5 access is globally serialized, so this
|
|
// is safe alongside the interactive reader), so the viewer becomes a processing frontend without
|
|
// blocking the UI. Cancel() is forwarded to Rugnux::Cancel() (atomic) and works from any
|
|
// thread / at any point of the run.
|
|
class JFJochProcessController : public QObject, private RugnuxObserver {
|
|
Q_OBJECT
|
|
public:
|
|
explicit JFJochProcessController(QObject *parent = nullptr);
|
|
~JFJochProcessController() override;
|
|
|
|
bool running() const { return running_; }
|
|
|
|
public slots:
|
|
// Start a job over `file_path` with the given (fully configured) experiment + mask + config.
|
|
// Ignored if a job is already running.
|
|
void start(const QString &file_path, DiffractionExperiment experiment,
|
|
PixelMask pixel_mask, ProcessConfig config);
|
|
void cancel();
|
|
|
|
signals:
|
|
void started();
|
|
void phaseChanged(QString phase);
|
|
void progress(quint64 done, quint64 total);
|
|
// `report` is the rugnux result report (the <prefix>_report.txt text), rendered from the run's
|
|
// own results so the viewer can show it without a file; empty for a cancelled run.
|
|
void finished(ProcessResult result, QString report);
|
|
void failed(QString error);
|
|
// Per-image results accumulated so far, for live dataset-info plots while a job runs (throttled).
|
|
void liveDataset(std::shared_ptr<const JFJochReaderDataset> dataset);
|
|
|
|
private:
|
|
// RugnuxObserver - called from worker threads, forwarded as queued signals.
|
|
void OnPhase(const std::string &phase) override;
|
|
void OnProgress(uint64_t done, uint64_t total) override;
|
|
void OnImageProcessed(const DataMessage &msg) override;
|
|
|
|
void run_(QString file_path, DiffractionExperiment experiment, PixelMask pixel_mask, ProcessConfig config);
|
|
void joinWorker_();
|
|
|
|
std::thread worker_;
|
|
std::atomic<Rugnux *> active_{nullptr};
|
|
std::atomic<bool> running_{false};
|
|
std::atomic<bool> cancel_pending_{false};
|
|
|
|
// Live per-image results, accumulated by OnImageProcessed (worker threads) and emitted as
|
|
// immutable copies. live_mutex_ guards both the dataset and the throttle timestamp.
|
|
std::mutex live_mutex_;
|
|
std::shared_ptr<JFJochReaderDataset> live_dataset_;
|
|
std::chrono::steady_clock::time_point last_live_emit_;
|
|
};
|