Files
Jungfraujoch/viewer/windows/JFJochProcessingJobsWindow.h
leonarski_fandClaude Opus 4.8 383072ac80 Consolidate viewer settings into the panel + add the merge-stats window
Make the inline settings dock the single home for processing settings and
retire the separate Processing-settings window (and the dock<->window sync):
- "Analyze image" / "Analyze dataset" move to the top of the panel; the
  MX/AzInt toggle decides the dataset-job kind, so the job dialog drops its
  mode combo.
- The panel gains the most-used spot-finding (max spots, high-resolution,
  min pixels), Bragg (Gaussian profile-fit, r1/r2/r3) and scaling (partiality,
  "3D rotation scaling" = rot3d combine + scale-fulls, merge Friedel, refine
  B, resolution limit) handles, a live indexing-algorithm description line,
  and now owns the Bragg/Scaling settings. The now-unused window tab classes
  are deleted.
- Complete the PixelRefine removal on the viewer side (the "Pixel refinement"
  option + profile-multiplier widget), fixing the transient HEAD breakage.

New JFJochMergeStatsWindow: an analysis pop-up for a finished merge (hero
numbers over a per-resolution plot / per-shell table), auto-opened on
completion and reopenable from the processing-jobs dock.

Fixes: disable tear-off dock floating (a floated dock is a dead off-screen
window under WSLg, which has no window manager); version the saved dock
layout so a stale arrangement is discarded instead of restoring a broken one;
keep the Analyze-button icons; right-align and equal-width the stats table;
line-plot / table toggle icons (ToolbarIcons gains linePlot + table).

Add ScalingSettings::HighResolutionLimit_A(optional) so the panel can clear
the resolution limit.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 20:43:04 +02:00

100 lines
4.4 KiB
C++

// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#pragma once
#include <QElapsedTimer>
#include <QString>
#include <QWidget>
#include <vector>
#include "../JFJochProcessController.h"
#include "../JFJochImageReadingWorker.h" // ReprocessingInputs
class QTableWidget;
class QProgressBar;
class QStackedWidget;
class QToolBar;
class QToolButton;
// Makes processing a first-class GUI activity: a dockable panel with a table of processing jobs run
// on the current dataset. A job can be run locally (off the GUI thread, via JFJochProcessController)
// or its jfjoch_process command line copied for a cluster. A finished local run is registered as a
// reader snapshot so its results become a selectable view of the dataset. Re-processing reads a
// stored HDF5 file, so the panel shows an explanatory message while connected to a live HTTP stream.
class JFJochProcessingJobsWindow : public QWidget {
Q_OBJECT
public:
explicit JFJochProcessingJobsWindow(JFJochImageReadingWorker *worker, QWidget *parent = nullptr);
signals:
void registerSnapshot(QString id, QString label, QString master_path);
void activateSnapshot(QString id);
void renameRun(QString id, QString label);
void removeRun(QString id);
void writeStatusBar(QString message, int timeout_ms = 0);
// Live per-image results while a job runs, for the dataset-info plots (nullptr clears it).
void liveDataset(std::shared_ptr<const JFJochReaderDataset> dataset);
void jobStarted(); // a reprocessing job was launched — reveal the (hidden-by-default) panel
public slots:
void onHttpConnectionChanged(bool connected, QString addr);
void clearJobs(); // reset the table on a new file (re-adds the Original row)
void setActiveRun(QString active_id); // bold the row of the run currently shown in the plots
void newJob(bool azint = false); // the panel's "Analyze dataset" action; azint = AzInt page
private slots:
void cancelJob();
void removeResult();
void viewResults();
void onPhase(QString phase);
void onProgress(quint64 done, quint64 total);
void onFinished(ProcessResult result);
void onFailed(QString error);
private:
struct JobInfo {
QString id; // stable reader-snapshot key
QString label; // editable display name (legend / table)
QString snapshot_path; // empty unless saved
bool has_result = false;
// Merge statistics captured when a scaling/merging job finished (drive the analysis window).
bool has_merge_stats = false;
MergeStatistics merge_stats;
double isa = 0.0;
bool merge_has_reference = false;
QToolButton *graph_btn = nullptr; // per-row "show statistics" button (enabled once stats exist)
};
struct JobSpec {
ProcessMode mode = ProcessMode::FullAnalysis;
int start_image = 0;
int end_image = 0; // 0 == to the end
int threads = 4;
bool save = true;
QString prefix;
bool rotation = false;
int rotation_images = 30; // images used to find the rotation lattice (first pass)
bool scaling = false;
};
// Returns 0 = cancel, 1 = run locally, 2 = copy command line; fills spec from the dialog.
int askJob(const ReprocessingInputs &inputs, JobSpec &spec, bool azint);
ProcessConfig buildConfig(const JobSpec &spec, const ReprocessingInputs &inputs) const;
void setStatus(int row, const QString &text);
void addOriginalRow(); // the file's own data as the first, always-present run
void addRowActions(int row, const QString &id); // per-row graph (stats) + trash (remove) buttons
void showStats(const QString &id); // open the merge-statistics window for a run
void removeRunById(const QString &id); // remove a run from the table + reader
JFJochImageReadingWorker *worker_;
JFJochProcessController *controller_;
QToolBar *toolbar_;
QStackedWidget *stack_; // page 0: jobs table, page 1: HTTP-mode message
QTableWidget *table_;
QProgressBar *running_bar_ = nullptr; // lives in the running row's Status cell
QElapsedTimer job_timer_; // running job wall-clock, for rate + ETA
int running_row_ = -1;
int job_counter_ = 0;
std::vector<JobInfo> jobs_;
};