viewer: add/subtract the selected ROI to/from the user mask
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Failing after 3m45s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Failing after 3m44s
Build Packages / build:rpm (rocky8_nocuda) (push) Failing after 3m50s
Build Packages / build:rpm (rocky8_sls9) (push) Failing after 3m45s
Build Packages / build:rpm (rocky8) (push) Failing after 3m46s
Build Packages / build:rpm (rocky9_nocuda) (push) Failing after 4m0s
Build Packages / build:rpm (rocky9_sls9) (push) Failing after 3m56s
Build Packages / build:rpm (ubuntu2204) (push) Failing after 3m5s
Build Packages / build:rpm (ubuntu2404) (push) Failing after 3m7s
Build Packages / build:rpm (rocky9) (push) Failing after 3m12s
Build Packages / Create release (push) Skipped
Build Packages / Build documentation (push) Failing after 21s
Build Packages / Generate python client (push) Successful in 31s
Build Packages / XDS test (durin plugin) (push) Successful in 5m53s
Build Packages / XDS test (neggia plugin) (push) Successful in 6m12s
Build Packages / XDS test (JFJoch plugin) (push) Successful in 6m54s
Build Packages / DIALS test (push) Successful in 8m46s
Build Packages / Unit tests (push) Successful in 48m22s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Failing after 3m45s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Failing after 3m44s
Build Packages / build:rpm (rocky8_nocuda) (push) Failing after 3m50s
Build Packages / build:rpm (rocky8_sls9) (push) Failing after 3m45s
Build Packages / build:rpm (rocky8) (push) Failing after 3m46s
Build Packages / build:rpm (rocky9_nocuda) (push) Failing after 4m0s
Build Packages / build:rpm (rocky9_sls9) (push) Failing after 3m56s
Build Packages / build:rpm (ubuntu2204) (push) Failing after 3m5s
Build Packages / build:rpm (ubuntu2404) (push) Failing after 3m7s
Build Packages / build:rpm (rocky9) (push) Failing after 3m12s
Build Packages / Create release (push) Skipped
Build Packages / Build documentation (push) Failing after 21s
Build Packages / Generate python client (push) Successful in 31s
Build Packages / XDS test (durin plugin) (push) Successful in 5m53s
Build Packages / XDS test (neggia plugin) (push) Successful in 6m12s
Build Packages / XDS test (JFJoch plugin) (push) Successful in 6m54s
Build Packages / DIALS test (push) Successful in 8m46s
Build Packages / Unit tests (push) Successful in 48m22s
Restore the ROI-to-mask action on the new list: "Add to mask" and "Subtract from mask" buttons rasterise the selected ROI into the user mask (set or clear), through the same UpdateUserMask_i path. The ROI is evaluated with per-pixel resolution and phi from the geometry, so box, circle and azimuthal (sector) ROIs all map correctly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -584,6 +584,37 @@ void JFJochImageReadingWorker::SetROIDefinition(const ROIDefinition &rois) {
|
||||
SetROIDefinition_i(rois);
|
||||
}
|
||||
|
||||
void JFJochImageReadingWorker::MaskFromSelectedROI(QString name, bool add) {
|
||||
QMutexLocker locker(&m);
|
||||
if (!current_image_ptr)
|
||||
return;
|
||||
|
||||
const auto &exp = current_image_ptr->Dataset().experiment;
|
||||
const auto rois = exp.ROI().GetROIDefinition();
|
||||
const std::string n = name.toStdString();
|
||||
|
||||
const ROIElement *elem = nullptr;
|
||||
for (const auto &b : rois.boxes) if (b.GetName() == n) { elem = &b; break; }
|
||||
if (!elem) for (const auto &c : rois.circles) if (c.GetName() == n) { elem = &c; break; }
|
||||
if (!elem) for (const auto &a : rois.azimuthal) if (a.GetName() == n) { elem = &a; break; }
|
||||
if (!elem)
|
||||
return;
|
||||
|
||||
auto user_mask = current_image_ptr->Dataset().pixel_mask.GetUserMask();
|
||||
auto geom = exp.GetDiffractionGeometry();
|
||||
const int64_t width = exp.GetXPixelsNum();
|
||||
const int64_t height = exp.GetYPixelsNum();
|
||||
for (int64_t y = 0; y < height; y++) {
|
||||
for (int64_t x = 0; x < width; x++) {
|
||||
const float res = geom.PxlToRes(x, y);
|
||||
const float phi = geom.Phi_rad(x, y) * 180.0f / static_cast<float>(PI);
|
||||
if (elem->CheckROI(x, y, res, phi))
|
||||
user_mask[x + y * width] = add ? 1 : 0;
|
||||
}
|
||||
}
|
||||
UpdateUserMask_i(user_mask);
|
||||
}
|
||||
|
||||
void JFJochImageReadingWorker::DownloadROIsFromServer() {
|
||||
QMutexLocker locker(&m);
|
||||
if (!http_mode)
|
||||
|
||||
@@ -166,6 +166,7 @@ public slots:
|
||||
void SetROIDefinition(const ROIDefinition &rois);
|
||||
void DownloadROIsFromServer();
|
||||
void UploadROIsToServer();
|
||||
void MaskFromSelectedROI(QString name, bool add); // rasterise an ROI into the user mask
|
||||
|
||||
void SaveUserMaskTIFF(QString filename);
|
||||
void LoadUserMaskTIFF(QString filename, bool replace);
|
||||
|
||||
@@ -132,6 +132,7 @@ JFJochViewerSidePanel::JFJochViewerSidePanel(QWidget *parent) : QWidget(parent)
|
||||
connect(roi_list, &JFJochViewerROIList::selectedROIChanged, this, &JFJochViewerSidePanel::selectedROIChanged);
|
||||
connect(roi_list, &JFJochViewerROIList::downloadROIs, this, &JFJochViewerSidePanel::downloadROIs);
|
||||
connect(roi_list, &JFJochViewerROIList::uploadROIs, this, &JFJochViewerSidePanel::uploadROIs);
|
||||
connect(roi_list, &JFJochViewerROIList::maskFromROI, this, &JFJochViewerSidePanel::maskFromROI);
|
||||
|
||||
layout->addWidget(new TitleLabel("Data analysis", this));
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ signals:
|
||||
void selectedROIChanged(QString name);
|
||||
void downloadROIs();
|
||||
void uploadROIs();
|
||||
void maskFromROI(QString name, bool add);
|
||||
void findBeamCenter(const UnitCell &input, bool guess);
|
||||
void analyze();
|
||||
|
||||
|
||||
@@ -201,6 +201,8 @@ JFJochViewerWindow::JFJochViewerWindow(QWidget *parent, bool dbus, const QString
|
||||
reading_worker, &JFJochImageReadingWorker::DownloadROIsFromServer);
|
||||
connect(side_panel, &JFJochViewerSidePanel::uploadROIs,
|
||||
reading_worker, &JFJochImageReadingWorker::UploadROIsToServer);
|
||||
connect(side_panel, &JFJochViewerSidePanel::maskFromROI,
|
||||
reading_worker, &JFJochImageReadingWorker::MaskFromSelectedROI);
|
||||
|
||||
connect(menuBar, &JFJochViewerMenu::clearUserMaskSelected,
|
||||
reading_worker, &JFJochImageReadingWorker::ClearUserMask);
|
||||
|
||||
@@ -55,6 +55,19 @@ JFJochViewerROIList::JFJochViewerROIList(QWidget *parent) : QWidget(parent) {
|
||||
}
|
||||
layout->addLayout(grid);
|
||||
|
||||
auto *mask = new QHBoxLayout();
|
||||
auto *mask_add = new QPushButton("Add to mask", this);
|
||||
auto *mask_sub = new QPushButton("Subtract from mask", this);
|
||||
mask->addWidget(mask_add);
|
||||
mask->addWidget(mask_sub);
|
||||
layout->addLayout(mask);
|
||||
connect(mask_add, &QPushButton::clicked, [this] {
|
||||
if (!SelectedName().isEmpty()) emit maskFromROI(SelectedName(), true);
|
||||
});
|
||||
connect(mask_sub, &QPushButton::clicked, [this] {
|
||||
if (!SelectedName().isEmpty()) emit maskFromROI(SelectedName(), false);
|
||||
});
|
||||
|
||||
result_ = new JFJochViewerROIResult(this);
|
||||
layout->addWidget(result_);
|
||||
}
|
||||
|
||||
@@ -52,4 +52,5 @@ signals:
|
||||
void selectedROIChanged(QString name);
|
||||
void downloadROIs(); // fetch ROIs from the connected broker
|
||||
void uploadROIs(); // push ROIs to the connected broker
|
||||
void maskFromROI(QString name, bool add); // add/subtract the selected ROI to/from the user mask
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user