diff --git a/viewer/JFJochImageReadingWorker.cpp b/viewer/JFJochImageReadingWorker.cpp index a86e4619..0e8de2c5 100644 --- a/viewer/JFJochImageReadingWorker.cpp +++ b/viewer/JFJochImageReadingWorker.cpp @@ -90,6 +90,7 @@ JFJochImageReadingWorker::JFJochImageReadingWorker(const SpotFindingSettings &se azint_settings(experiment.GetAzimuthalIntegrationSettings()) { qRegisterMetaType>("QVector"); qRegisterMetaType("BrokerStatus"); + qRegisterMetaType("ROIDefinition"); spot_finding_settings = settings; indexing = std::make_unique(indexing_settings); @@ -382,8 +383,16 @@ void JFJochImageReadingWorker::LoadImage_i(int64_t image_number, int64_t summati auto end = std::chrono::high_resolution_clock::now(); - if (auto_reanalyze) + if (auto_reanalyze) { ReanalyzeImage_i(); + } else if (image_analysis && !curr_experiment.ROI().empty()) { + // ROIs are wanted even when a full re-analysis is not; compute only those. + try { + image_analysis->AnalyzeROIOnly(current_image_ptr->ImageData()); + } catch (const std::exception &e) { + logger.Error("ROI-only analysis failed: {}", e.what()); + } + } auto end_analysis = std::chrono::high_resolution_clock::now(); @@ -580,6 +589,40 @@ void JFJochImageReadingWorker::UpdateAzintSettings(const AzimuthalIntegrationSet UpdateDataset_i(std::nullopt); } +void JFJochImageReadingWorker::SetROIDefinition(const ROIDefinition &rois) { + QMutexLocker locker(&m); + SetROIDefinition_i(rois); +} + +void JFJochImageReadingWorker::SetROIDefinition_i(const ROIDefinition &rois) { + // The worker experiment is the source of truth; the analysis ROI engine is rebuilt + // for it so newly loaded images pick up the change automatically. + curr_experiment.ROI().SetROI(rois); + if (image_analysis) + image_analysis->RebuildROI(); + + if (!current_image_ptr) + return; + + // Mutate the dataset too, so the canvas (which draws image->Dataset().experiment.ROI()) + // reflects the edit, then recompute only the ROIs for the current image. + auto mutable_dataset = current_image_ptr->CreateMutableDataset(); + mutable_dataset->experiment.ROI().SetROI(rois); + std::shared_ptr dataset = mutable_dataset; + current_image_ptr = std::make_shared(current_image_ptr->ImageData(), dataset); + + if (image_analysis) { + try { + image_analysis->RunROIOnly(current_image_ptr->ImageData()); + } catch (const std::exception &e) { + logger.Error("ROI-only analysis failed: {}", e.what()); + } + } + + emit datasetLoaded(dataset); + emit imageLoaded(current_image_ptr); +} + void JFJochImageReadingWorker::UpdateUserMask_i(const std::vector &mask) { std::shared_ptr dataset; if (http_mode) { diff --git a/viewer/JFJochImageReadingWorker.h b/viewer/JFJochImageReadingWorker.h index 07144f52..3db9e495 100644 --- a/viewer/JFJochImageReadingWorker.h +++ b/viewer/JFJochImageReadingWorker.h @@ -31,6 +31,7 @@ Q_DECLARE_METATYPE(AzimuthalIntegrationSettings) Q_DECLARE_METATYPE(UnitCell) Q_DECLARE_METATYPE(std::shared_ptr) Q_DECLARE_METATYPE(BrokerStatus) +Q_DECLARE_METATYPE(ROIDefinition) class JFJochImageReadingWorker : public QObject { Q_OBJECT @@ -117,6 +118,7 @@ private: void UpdateDataset_i(const std::optional& experiment); void UpdateAzint_i(const JFJochReaderDataset *dataset); void UpdateUserMask_i(const std::vector &mask); + void SetROIDefinition_i(const ROIDefinition &rois); void setAutoLoadMode_i(AutoloadMode mode); signals: @@ -164,6 +166,8 @@ public slots: void AddROIToUserMask(); void SubtractROIFromUserMask(); + void SetROIDefinition(const ROIDefinition &rois); + void SaveUserMaskTIFF(QString filename); void UploadUserMask(); void ClearUserMask();