jfjoch_viewer: fixes to pixel refine
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 9m11s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 10m45s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 11m5s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 10m58s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 11m12s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 11m39s
Build Packages / build:rpm (rocky8) (push) Successful in 9m40s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 10m0s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 10m11s
Build Packages / build:rpm (rocky9) (push) Successful in 11m13s
Build Packages / Create release (push) Skipped
Build Packages / Generate python client (push) Successful in 18s
Build Packages / Build documentation (push) Successful in 40s
Build Packages / XDS test (durin plugin) (push) Successful in 8m21s
Build Packages / DIALS test (push) Successful in 12m45s
Build Packages / XDS test (JFJoch plugin) (push) Successful in 7m6s
Build Packages / XDS test (neggia plugin) (push) Successful in 5m55s
Build Packages / Unit tests (push) Successful in 2h7m17s

This commit is contained in:
2026-06-09 12:35:06 +02:00
parent 8a582b8a90
commit feca63f4b9
3 changed files with 52 additions and 19 deletions
+32 -9
View File
@@ -729,18 +729,31 @@ void JFJochImageReadingWorker::EnsurePixelRefine_i() {
pixel_pred_ = CreateBraggPrediction(curr_experiment.IsRotationIndexing());
}
bool JFJochImageReadingWorker::BuildPixelSeed_i(PixelRefineData &d, const PixelRefineParams &p) const {
if (!current_image_ptr || !index_and_refine || !current_image.has_value())
bool JFJochImageReadingWorker::BuildPixelSeed_i(PixelRefineData &d, const PixelRefineParams &p, QString &reason) const {
if (!current_image_ptr || !index_and_refine || !current_image.has_value()) {
reason = "No image loaded";
return false;
}
const auto &outcomes = index_and_refine->GetIntegrationOutcome();
const int64_t n = current_image.value();
if (n < 0 || n >= static_cast<int64_t>(outcomes.size()))
if (n < 0 || n >= static_cast<int64_t>(outcomes.size())) {
reason = "No analysis result for current image";
return false;
}
const auto &io = outcomes[n];
if (io.reflections.empty()) // image not indexed/integrated
if (io.reflections.empty()) {
// The "indexed" badge in the viewer comes from indexing (lattice_type);
// PixelRefine instead seeds from the *integration* outcome, which is only
// populated when Quick integration is enabled and succeeds for this image.
// Distinguish the two so the user knows what to turn on.
if (current_image_ptr->ImageData().lattice_type.has_value())
reason = "Image is indexed but not integrated - enable Quick integration";
else
reason = "Current image is not indexed";
return false;
}
d.geom = io.geom;
d.latt = io.latt;
@@ -773,7 +786,15 @@ bool JFJochImageReadingWorker::BuildPixelSeed_i(PixelRefineData &d, const PixelR
std::shared_ptr<SimpleImage> JFJochImageReadingWorker::WrapFloatImage_i(const std::vector<float> &img) const {
auto si = std::make_shared<SimpleImage>();
si->image = CompressedImage(img, curr_experiment.GetXPixelsNum(), curr_experiment.GetYPixelsNum());
// CompressedImage is a non-owning view over its data pointer. predictedImageReady
// is a queued cross-thread connection, so the source float vector must outlive the
// emit: copy it into SimpleImage::buffer (which the shared_ptr keeps alive) instead
// of aliasing the caller's temporary, otherwise loadImageInternal() reads freed
// memory in the GUI thread (SIGSEGV).
si->buffer.resize(img.size() * sizeof(float));
std::memcpy(si->buffer.data(), img.data(), si->buffer.size());
si->image = CompressedImage(si->buffer, curr_experiment.GetXPixelsNum(), curr_experiment.GetYPixelsNum(),
CompressedImageMode::Float32);
return si;
}
@@ -803,8 +824,9 @@ void JFJochImageReadingWorker::PixelRefinePreview(PixelRefineParams params) {
}
PixelRefineData d;
if (!BuildPixelSeed_i(d, params)) {
emit pixelRefineStatus("Current image is not indexed");
QString seed_reason;
if (!BuildPixelSeed_i(d, params, seed_reason)) {
emit pixelRefineStatus(seed_reason);
return;
}
@@ -838,8 +860,9 @@ void JFJochImageReadingWorker::PixelRefineRun(PixelRefineParams params) {
}
PixelRefineData d;
if (!BuildPixelSeed_i(d, params)) {
emit pixelRefineStatus("Current image is not indexed");
QString seed_reason;
if (!BuildPixelSeed_i(d, params, seed_reason)) {
emit pixelRefineStatus(seed_reason);
return;
}
if (d.max_iterations <= 0)
+1 -1
View File
@@ -69,7 +69,7 @@ private:
std::unique_ptr<BraggPrediction> pixel_pred_;
void EnsurePixelRefine_i();
bool BuildPixelSeed_i(PixelRefineData &d, const PixelRefineParams &p) const;
bool BuildPixelSeed_i(PixelRefineData &d, const PixelRefineParams &p, QString &reason) const;
std::shared_ptr<SimpleImage> WrapFloatImage_i(const std::vector<float> &img) const;
std::unique_ptr<ROIElement> roi;
+19 -9
View File
@@ -145,16 +145,26 @@ void JFJochPixelRefineWindow::onControlChanged() {
}
void JFJochPixelRefineWindow::imageLoaded(std::shared_ptr<const JFJochReaderImage> image) {
if (m_beamInit || !image)
if (!image)
return;
const auto geom = image->Dataset().experiment.GetDiffractionGeometry();
m_beamx->setMax(static_cast<double>(image->Dataset().experiment.GetXPixelsNum()));
m_beamy->setMax(static_cast<double>(image->Dataset().experiment.GetYPixelsNum()));
m_suppress = true;
m_beamx->setValue(geom.GetBeamX_pxl());
m_beamy->setValue(geom.GetBeamY_pxl());
m_suppress = false;
m_beamInit = true;
// Initialise the beam-centre sliders from the geometry once.
if (!m_beamInit) {
const auto geom = image->Dataset().experiment.GetDiffractionGeometry();
m_beamx->setMax(static_cast<double>(image->Dataset().experiment.GetXPixelsNum()));
m_beamy->setMax(static_cast<double>(image->Dataset().experiment.GetYPixelsNum()));
m_suppress = true;
m_beamx->setValue(geom.GetBeamX_pxl());
m_beamy->setValue(geom.GetBeamY_pxl());
m_suppress = false;
m_beamInit = true;
}
// Request a predicted-image preview for the (re)loaded image. Without this the
// preview only refreshed on a slider change, so opening/reanalyzing an image
// left the predicted view empty. The worker no-ops if there is no reference or
// the image is not integrated yet.
onControlChanged();
}
void JFJochPixelRefineWindow::setPredictedImage(std::shared_ptr<const SimpleImage> image) {