Files
Jungfraujoch/viewer/JFJochViewerWindow.h
T
leonarski_f 84228bf8be
Build Packages / Create release (push) Successful in 24s
Build Packages / build:viewer:macos-arm64:nocuda (push) Successful in 3m29s
Build Packages / build:rugnux:macos-arm64:nocuda (push) Successful in 2m43s
Build Packages / build:rugnux:linux-aarch64:cuda (push) Successful in 8m27s
Build Packages / build:rugnux:linux-x86_64:cuda (push) Successful in 9m53s
Build Packages / build:viewer:linux-x86_64:nocuda (push) Successful in 9m58s
Build Packages / build:viewer:linux-x86_64:cuda (push) Successful in 11m22s
Build Packages / build:jfjoch:rocky8:nocuda (push) Successful in 13m39s
Build Packages / build:viewer:windows-x86_64:nocuda (push) Successful in 18m37s
Build Packages / build:jfjoch:rocky9:nocuda (push) Successful in 16m32s
Build Packages / build:viewer:windows-x86_64:cuda (push) Successful in 24m11s
Build Packages / HDF5 consumer tests (DIALS, XDS) (push) Successful in 25m30s
Build Packages / build:jfjoch:ubuntu2404:nocuda (push) Successful in 19m3s
Build Packages / build:jfjoch:ubuntu2204:nocuda (push) Successful in 20m23s
Build Packages / build:jfjoch:rocky8:cuda-sls9 (push) Successful in 19m41s
Build Packages / Generate python client (push) Successful in 50s
Build Packages / Build documentation (push) Successful in 1m16s
Build Packages / build:jfjoch:rocky9:cuda-sls9 (push) Successful in 21m0s
Build Packages / build:jfjoch:rocky8:cuda (push) Successful in 18m38s
Build Packages / build:rugnux:windows-x86_64:cuda (push) Successful in 14m33s
Build Packages / build:jfjoch:rocky9:cuda (push) Successful in 17m55s
Build Packages / build:jfjoch:ubuntu2204:cuda (push) Successful in 20m50s
Build Packages / build:jfjoch:ubuntu2404:cuda (push) Successful in 18m38s
Build Packages / Unit tests (push) Successful in 1h46m14s
v1.0.0-rc.173 (#83)
* jfjoch_broker: Optional per-dataset authentication - statistics, images and plots can require a bearer token, which jfjoch_viewer supports.
* jfjoch_viewer: Dark mode and a theme-matched colour scheme, a magnifier panel, and simpler contrast and background controls.
* Rugnux: Multiple performance improvements on GPU and CPU (CPU-only processing up to 40% faster, faster image decoding on ARM), with unchanged results.
* Rugnux: `--model` rigid-body refinement runs on the GPU, and the model-validation check is faster and more reliable.
* Rugnux: Improved scaling and merging - error model, outlier rejection, absorption correction and French-Wilson amplitudes now agree more closely with XDS and ctruncate.
* Rugnux: Improved integration - radial background on powder and ice rings, crowded rotation data keep their reflections, and CPU-only builds integrate large unit cells as GPU builds do.
* Rugnux: More robust detector geometry - measured beam centre, X-ray bandwidth and goniometer rate, and geometry refinement accepted only on significant evidence.
* Rugnux: Merged files are written in the standard setting, or in the setting of a reference MTZ, structure-factor mmCIF or model, with its free-R flags.
* Rugnux: Richer report - ice and powder rings, further lattices, superstructure candidates and mosaicity, with warnings worded as prompts to check.
* Rugnux: Clear error messages when a data set needs more GPU or host memory than is available.

Reviewed-on: #83
Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch>
2026-09-29 15:57:32 +02:00

136 lines
6.6 KiB
C++

// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#pragma once
#include <QElapsedTimer>
#include <QMainWindow>
#include <QProgressDialog>
#include <QTimer>
#include "JFJochViewerMenu.h"
#include "../reader/JFJochHDF5Reader.h"
#include "JFJochImageReadingWorker.h"
#include "JFJochViewerDatasetInfo.h"
#include "JFJochViewerStatusBar.h"
#include "toolbar/JFJochViewerToolbarDisplay.h"
class JFJochProcessingJobsWindow;
class JFJochDiffractionImage;
class JFJochHelperWindow;
class JFJochViewerMagnifier;
class QDockWidget;
class QScrollArea;
class JFJochViewerWindow : public QMainWindow {
Q_OBJECT
// Theming is done via the application palette in main() (salmon panels, white entry fields,
// navy accent) so it applies consistently to every widget, including dialogs.
public:
explicit JFJochViewerWindow(QWidget *parent = nullptr, bool dbus = true, const QString &file = "");
~JFJochViewerWindow() override;
private:
JFJochViewerMenu *menuBar;
JFJochImageReadingWorker *reading_worker;
JFJochDiffractionImage *viewer; // central diffraction image
JFJochViewerToolbarDisplay *toolBarDisplay;
JFJochViewerStatusBar *statusbar;
JFJochProcessingJobsWindow *processingJobsWindow;
std::shared_ptr<const JFJochReaderDataset> lastDataset; // added
std::shared_ptr<const JFJochReaderImage> lastImage; // added
// Remote-display frame throttle (see OnImageReady): the newest frame not yet fanned out,
// delivered at most every kRemoteRepaintIntervalMs while a fast producer runs.
std::shared_ptr<const JFJochReaderImage> pendingImage;
QElapsedTimer image_rate_;
QTimer *image_tail_timer_ = nullptr;
void DeliverPendingImage();
QVector<RunData> lastRuns; // for dataset-info docks opened later
QString lastActiveRunId;
QProgressDialog *retryDialog = nullptr;
QDockWidget *lastDatasetInfoDock = nullptr; // most recent dataset-info dock, for docking layout
QDockWidget *inspectorDock = nullptr; // image inspector (former right-hand side panel)
QScrollArea *inspectorScroll = nullptr; // its scroll area; width bounds follow the font
QDockWidget *settingsDock = nullptr; // inline MX/AzInt settings panel
QDockWidget *fileBrowserDock = nullptr; // data-root directory tree, tabbed with settingsDock
QDockWidget *processingDock = nullptr; // processing jobs panel
JFJochViewerMagnifier *magnifier = nullptr;
QDockWidget *magnifierDock = nullptr; // where the magnifier normally sits
JFJochHelperWindow *magnifierWindow = nullptr; // ... and its window when popped out
void PopOutMagnifier();
QByteArray defaultLayoutState; // captured after construction, for "Reset layout"
int datasetInfoCounter = 0; // gives each dataset-info dock a unique objectName
void ResetAllSettings();
void UpdateInspectorWidth();
// A narrow window folds the inspector away (with the magnifier, when it is docked in the same
// column) so the image keeps its room, and brings it back once the window is wide enough again.
QList<QDockWidget *> autoHiddenDocks; // hidden by the window, not by the user
int autoHiddenWidth = 0; // the inspector column's width when it was folded away
void resizeEvent(QResizeEvent *event) override;
// Both ways of opening a dataset from outside the file manager - the File menu and D-Bus -
// come through here, so the browser follows the same way for either.
void FollowInFileBrowser(const QString &filename);
QThread *reading_thread;
// Named layouts. Image = just the image + inspector; Processing = also the plots + jobs panel.
enum class Perspective { Image, Processing };
void ApplyPerspective(Perspective p);
// Keyboard shortcuts (F/B/A, Home/End/PageUp/PageDown) are handled in an application-wide
// event filter rather than keyPressEvent, so they work wherever the focus happens to be,
// stepping aside when the focused widget genuinely uses the key (text entry, item views).
bool eventFilter(QObject *obj, QEvent *event) override;
void closeEvent(QCloseEvent *event) override;
void changeEvent(QEvent *event) override;
private slots:
// Single cross-thread sink for the worker's imageLoaded: fans out to every GUI consumer
// (synchronously, same thread) via imageReady, then acks the worker so it may produce the next.
void OnImageReady(std::shared_ptr<const JFJochReaderImage> image);
// Single cross-thread sink for the worker's datasetLoaded, mirroring OnImageReady: fans out to
// every GUI consumer synchronously via datasetReady, then acks the worker (datasetConsumed) so the
// worker can cap how many datasets are in flight - without this the queued datasetLoaded backlog
// (each event pinning a full dataset) grew without bound in live follow (100 GB OOM).
void OnDatasetReady(std::shared_ptr<const JFJochReaderDataset> dataset);
public slots:
void LoadFile(const QString &filename, qint64 image_number, qint64 summation, bool retry);
void LoadImage(qint64 image_number, qint64 summation);
// The bearer token for a protected broker dataset. Sources, each overriding the previous:
// JUNGFRAUJOCH_HTTP_TOKEN at start-up, D-Bus, the Open HTTP Connection dialog.
void SetHttpToken(const QString &token);
void NewDatasetInfo();
void OnFileLoadError(QString title, QString message);
void OnFileLoadRetryStatus(bool active, QString message);
signals:
// Internal GUI-thread fan-out of the newest frame: OnImageReady re-emits this to every GUI
// consumer synchronously, then acks via imageConsumed (see OnImageReady).
void imageReady(std::shared_ptr<const JFJochReaderImage> image);
void imageConsumed(); // ack to the worker that one frame has been consumed (backpressure)
// Same GUI-thread fan-out + ack for the dataset stream (see OnDatasetReady).
void datasetReady(std::shared_ptr<const JFJochReaderDataset> dataset);
void datasetConsumed(); // ack to the worker that one dataset has been consumed (backpressure)
void LoadFileRequest(const QString &filename, qint64 image_number, qint64 summation, bool retry);
void LoadImageRequest(int64_t image_number, int64_t summation);
void HttpTokenRequest(QString token);
void adjustForegroundButton(bool input);
void adjustBackgroundButton(bool input);
void setAutoForeground(bool val);
void oneShotAutoForeground();
// Re-emitted by the shortcut filter; the navigation toolbar applies the step, clamped.
void stepImage(int steps);
};