viewer: worker can update ROIs and recompute them without full re-analysis
The reading worker's experiment is the source of truth for ROIs. Add a SetROIDefinition slot that updates curr_experiment.ROI(), rebuilds the analysis ROI engine, mutates the dataset (so the canvas reflects the new ROIs) and recomputes only the ROIs for the current image via RunROIOnly. On image load when full re-analysis is off, ROIs are still computed via AnalyzeROIOnly so the statistics stay current. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -90,6 +90,7 @@ JFJochImageReadingWorker::JFJochImageReadingWorker(const SpotFindingSettings &se
|
||||
azint_settings(experiment.GetAzimuthalIntegrationSettings()) {
|
||||
qRegisterMetaType<QVector<QRect>>("QVector<QRect>");
|
||||
qRegisterMetaType<BrokerStatus>("BrokerStatus");
|
||||
qRegisterMetaType<ROIDefinition>("ROIDefinition");
|
||||
spot_finding_settings = settings;
|
||||
|
||||
indexing = std::make_unique<IndexerThreadPool>(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<const JFJochReaderDataset> dataset = mutable_dataset;
|
||||
current_image_ptr = std::make_shared<JFJochReaderImage>(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<uint32_t> &mask) {
|
||||
std::shared_ptr<const JFJochReaderDataset> dataset;
|
||||
if (http_mode) {
|
||||
|
||||
@@ -31,6 +31,7 @@ Q_DECLARE_METATYPE(AzimuthalIntegrationSettings)
|
||||
Q_DECLARE_METATYPE(UnitCell)
|
||||
Q_DECLARE_METATYPE(std::shared_ptr<const SimpleImage>)
|
||||
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<DiffractionExperiment>& experiment);
|
||||
void UpdateAzint_i(const JFJochReaderDataset *dataset);
|
||||
void UpdateUserMask_i(const std::vector<uint32_t> &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();
|
||||
|
||||
Reference in New Issue
Block a user