viewer: indexing algorithm/refinement radio groups, rotation fix, live job plots
Processing settings: - Split the spot/index settings widget into two tabs (Spot finding | Indexing) via TakeSpotFindingPage()/TakeIndexingPage(). - Indexing tab now exposes the indexing algorithm (Auto/FFBIDX/FFT/FFTW/None) and geometry refinement (None/Orientation/Beam center/Pixel refine) as radio groups with short explanations. - Fix: UpdateSpotFindingSettings dropped algorithm + geometry-refinement when copying into indexing_settings (the geom checkbox was a no-op); both now flow into jobs via curr_experiment. Processing jobs window: - Rotation indexing from the job dialog now also sets RotationIndexing(true) on the experiment's IndexingSettings; otherwise IndexAndRefine builds no rotation indexer and the two-pass pre-pass throws. - Status cell shows a QProgressBar with "<done> / <expected>". - Live results: JFJochProcessController::OnImageProcessed accumulates per-image results into a JFJochReaderDataset and emits it throttled (~4 Hz) as liveDataset, forwarded to the dataset-info plots so they update while a job runs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -6,8 +6,11 @@
|
||||
|
||||
#include <QMetaType>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
JFJochProcessController::JFJochProcessController(QObject *parent) : QObject(parent) {
|
||||
qRegisterMetaType<ProcessResult>("ProcessResult");
|
||||
qRegisterMetaType<std::shared_ptr<const JFJochReaderDataset>>("std::shared_ptr<const JFJochReaderDataset>");
|
||||
}
|
||||
|
||||
JFJochProcessController::~JFJochProcessController() {
|
||||
@@ -44,6 +47,16 @@ void JFJochProcessController::run_(QString file_path, DiffractionExperiment expe
|
||||
JFJochHDF5Reader reader;
|
||||
reader.ReadFile(file_path.toStdString());
|
||||
|
||||
// Seed the live dataset with the experiment so the chart has geometry context; per-image
|
||||
// results are filled in by OnImageProcessed as the run progresses.
|
||||
{
|
||||
auto base = std::make_shared<JFJochReaderDataset>();
|
||||
base->experiment = experiment;
|
||||
std::lock_guard lock(live_mutex_);
|
||||
live_dataset_ = std::move(base);
|
||||
last_live_emit_ = {};
|
||||
}
|
||||
|
||||
JFJochProcess process(reader, std::move(experiment), std::move(pixel_mask), std::move(config));
|
||||
active_ = &process;
|
||||
if (cancel_pending_)
|
||||
@@ -71,3 +84,45 @@ void JFJochProcessController::OnProgress(uint64_t done, uint64_t total) {
|
||||
if (done == total || done % step == 0)
|
||||
emit progress(done, total);
|
||||
}
|
||||
|
||||
void JFJochProcessController::OnImageProcessed(const DataMessage &msg) {
|
||||
std::shared_ptr<JFJochReaderDataset> snapshot;
|
||||
{
|
||||
std::lock_guard lock(live_mutex_);
|
||||
if (!live_dataset_)
|
||||
return;
|
||||
|
||||
// Place each available per-image result at its ordinal; gaps (images still being processed
|
||||
// by other threads) read back as NaN.
|
||||
const int64_t i = msg.number;
|
||||
auto put = [i](std::vector<float> &v, float val) {
|
||||
if (static_cast<int64_t>(v.size()) <= i)
|
||||
v.resize(i + 1, NAN);
|
||||
v[i] = val;
|
||||
};
|
||||
auto &d = *live_dataset_;
|
||||
if (msg.spot_count) put(d.spot_count, *msg.spot_count);
|
||||
if (msg.spot_count_indexed) put(d.spot_count_indexed, *msg.spot_count_indexed);
|
||||
if (msg.spot_count_low_res) put(d.spot_count_low_res, *msg.spot_count_low_res);
|
||||
if (msg.spot_count_ice_rings) put(d.spot_count_ice_rings, *msg.spot_count_ice_rings);
|
||||
if (msg.indexing_result) put(d.indexing_result, *msg.indexing_result ? 1.0f : 0.0f);
|
||||
if (msg.indexing_lattice_count) put(d.indexing_lattice_count, *msg.indexing_lattice_count);
|
||||
if (msg.bkg_estimate) put(d.bkg_estimate, *msg.bkg_estimate);
|
||||
if (msg.resolution_estimate) put(d.resolution_estimate, *msg.resolution_estimate);
|
||||
if (msg.profile_radius) put(d.profile_radius, *msg.profile_radius);
|
||||
if (msg.mosaicity_deg) put(d.mosaicity_deg, *msg.mosaicity_deg);
|
||||
if (msg.b_factor) put(d.b_factor, *msg.b_factor);
|
||||
if (msg.integrated_reflections) put(d.integrated_reflections, *msg.integrated_reflections);
|
||||
if (msg.image_scale_factor) put(d.image_scale_factor, *msg.image_scale_factor);
|
||||
if (msg.image_scale_cc) put(d.image_scale_cc, *msg.image_scale_cc);
|
||||
if (msg.image_scale_b_factor) put(d.image_scale_b, *msg.image_scale_b_factor);
|
||||
|
||||
// Throttle to ~4 Hz so the GUI plots refresh smoothly without flooding the event queue.
|
||||
const auto now = std::chrono::steady_clock::now();
|
||||
if (now - last_live_emit_ < std::chrono::milliseconds(250))
|
||||
return;
|
||||
last_live_emit_ = now;
|
||||
snapshot = std::make_shared<JFJochReaderDataset>(d); // immutable copy for the GUI thread
|
||||
}
|
||||
emit liveDataset(snapshot);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user