jfjoch_viewer: Clean-up user interface (let's follow if it is not too crowded)

This commit is contained in:
2025-11-06 10:44:00 +01:00
parent 76d4e04b90
commit 2b372ba794
4 changed files with 160 additions and 122 deletions
+1 -1
View File
@@ -271,7 +271,7 @@ void JFJochImageReadingWorker::FindCenter(const UnitCell& calibrant, bool guess)
std::vector<float> ring_Q = CalculateXtalRings(calibrant);
QVector<float> rings;
for (int i = 0; i < 6 && i < ring_Q.size(); i++) {
for (int i = 0; i < 10 && i < ring_Q.size(); i++) {
rings.push_back(2 * M_PI / ring_Q[i]);
}
emit setRings(rings);
+49 -24
View File
@@ -3,23 +3,26 @@
#include "JFJochViewerImageROIStatistics.h"
#include "QVBoxLayout"
#include <QVBoxLayout>
#include <QHBoxLayout>
JFJochViewerImageROIStatistics::JFJochViewerImageROIStatistics(QWidget *parent)
: QWidget(parent) {
QVBoxLayout *layout = new QVBoxLayout(this);
box_radio = new QRadioButton("Box", this);
layout->addWidget(box_radio);
box_settings = new JFJochViewerImageROIStatistics_Box(this);
layout->addWidget(box_settings);
QHBoxLayout *box_row = new QHBoxLayout();
box_row->addWidget(box_radio);
box_row->addWidget(box_settings);
layout->addLayout(box_row);
circle_radio = new QRadioButton("Circle", this);
layout->addWidget(circle_radio);
circle_settings = new JFJochViewerImageROIStatistics_Circle(this);
layout->addWidget(circle_settings);
QHBoxLayout *circle_row = new QHBoxLayout();
circle_row->addWidget(circle_radio);
circle_row->addWidget(circle_settings);
layout->addLayout(circle_row);
radio_group = new QButtonGroup(this);
radio_group->addButton(box_radio, 1);
@@ -35,39 +38,61 @@ JFJochViewerImageROIStatistics::JFJochViewerImageROIStatistics(QWidget *parent)
circle_settings->Disable();
box_radio->setChecked(true);
layout->addWidget(new QLabel("", this));
roi_label = new QLabel("", this);
layout->addWidget(roi_label);
QHBoxLayout *label_row = new QHBoxLayout();
roi_sum = new QLabel("", this);
label_row->addWidget(roi_sum);
roi_mean = new QLabel("", this);
label_row->addWidget(roi_mean);
roi_var = new QLabel("", this);
label_row->addWidget(roi_var);
roi_max = new QLabel("", this);
label_row->addWidget(roi_max);
roi_npixel = new QLabel("", this);
label_row->addWidget(roi_npixel);
layout->addLayout(label_row);
QPushButton *add_button = new QPushButton("Add ROI to user mask", this);
connect(add_button, &QPushButton::clicked, [this]() { emit AddROIToUserMask(); });
layout->addWidget(add_button);
QPushButton *sub_button = new QPushButton("Subtract ROI from user mask", this);
connect(sub_button, &QPushButton::clicked, [this]() { emit SubtractROIFromUserMask(); });
layout->addWidget(sub_button);
QHBoxLayout *buttons_row = new QHBoxLayout();
buttons_row->setSpacing(12);
buttons_row->addWidget(add_button);
buttons_row->addWidget(sub_button);
layout->addLayout(buttons_row);
}
void JFJochViewerImageROIStatistics::loadImage(std::shared_ptr<const JFJochReaderImage> image) {
if (!image) {
roi_label->setText("");
roi_sum->setText("");
roi_mean->setText("");
roi_var->setText("");
roi_max->setText("");
roi_npixel->setText("");
} else {
auto roi = image->GetROI();
if (roi && roi->pixels > 0) {
auto roi_npixel = static_cast<double>(roi->pixels);
double roi_mean_val = static_cast<double>(roi->sum) / roi_npixel;
double variance = static_cast<double>(roi->sum_square) / roi_npixel - roi_mean_val * roi_mean_val;
auto roi_npixel_val = static_cast<double>(roi->pixels);
double roi_mean_val = static_cast<double>(roi->sum) / roi_npixel_val;
double variance = static_cast<double>(roi->sum_square) / roi_npixel_val - roi_mean_val * roi_mean_val;
QString text = QString("Sum <b>%1</b> Mean <b>%2</b> Var <b>%3</b> Max <b>%4</b> Pixels <b>%5</b>")
.arg(roi->sum)
.arg(QString::number(roi_mean_val, 'f', 3))
.arg(QString::number(variance, 'f', 3))
.arg(roi->max_count)
.arg(roi->pixels);
roi_label->setText(text);
roi_sum->setText(QString("Sum <b>%1</b>").arg(roi->sum));
roi_mean->setText(QString("Mean <b>%1</b>").arg(QString::number(roi_mean_val, 'f', 3)));
roi_var->setText(QString("Var <b>%1</b>").arg(QString::number(variance, 'f', 3)));
roi_max->setText(QString("Max <b>%1</b>").arg(roi->max_count));
roi_npixel->setText(QString("Pixels <b>%1</b>").arg(roi->pixels));
} else {
roi_label->setText("");
roi_sum->setText("");
roi_mean->setText("");
roi_var->setText("");
roi_max->setText("");
roi_npixel->setText("");
}
}
}
+5 -2
View File
@@ -25,8 +25,11 @@ class JFJochViewerImageROIStatistics : public QWidget {
JFJochViewerImageROIStatistics_Box *box_settings;
JFJochViewerImageROIStatistics_Circle *circle_settings;
QLabel *roi_pos;
QLabel *roi_label;
QLabel *roi_sum;
QLabel *roi_mean;
QLabel *roi_var;
QLabel *roi_max;
QLabel *roi_npixel;
public:
JFJochViewerImageROIStatistics(QWidget *parent);
private slots:
+105 -95
View File
@@ -3,7 +3,7 @@
#include <QCheckBox>
#include <QLabel>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QColorDialog>
@@ -14,6 +14,7 @@
#include "JFJochViewerImageROIStatistics.h"
#include "widgets/TitleLabel.h"
#include "JFJochViewerImageStatistics.h"
#include "../image_analysis/geom_refinement/AssignSpotsToRings.h"
JFJochViewerSidePanel::JFJochViewerSidePanel(QWidget *parent) : QWidget(parent) {
@@ -25,6 +26,97 @@ JFJochViewerSidePanel::JFJochViewerSidePanel(QWidget *parent) : QWidget(parent)
layout->addWidget(stats);
connect(this, &JFJochViewerSidePanel::imageLoaded, stats, &JFJochViewerImageStatistics::loadImage);
layout->addWidget(new TitleLabel("Image features", this));
// Image features...
auto spotToggleCheckBox = new QCheckBox("Show spots", this);
spotToggleCheckBox->setCheckState(Qt::CheckState::Checked);
connect(spotToggleCheckBox, &QCheckBox::toggled, this, &JFJochViewerSidePanel::spotsToggled);
auto highlightIceRingToggleCheckBox = new QCheckBox("Highlight spots on ice rings", this);
highlightIceRingToggleCheckBox->setCheckState(Qt::CheckState::Checked);
connect(highlightIceRingToggleCheckBox, &QCheckBox::toggled, this,&JFJochViewerSidePanel::highlightIceRingsToggled);
auto predictionsToggleCheckBox = new QCheckBox("Show predictions", this);
predictionsToggleCheckBox->setCheckState(Qt::CheckState::Unchecked);
connect(predictionsToggleCheckBox, &QCheckBox::toggled, this,
&JFJochViewerSidePanel::predictionsToggled);
resRingsCheckBox = new QCheckBox("Show resolution rings", this);
resRingsCheckBox->setCheckState(Qt::Unchecked);
autoResRingsCheckBox = new QCheckBox("Resolution rings auto.", this);
res_rings_edit = new QLineEdit(this);
res_rings_edit->setPlaceholderText("Ring positions, e.g., 1.0,2.5,3.7");
res_rings_edit->setEnabled(false); // Initially disabled as "Auto Res Rings" is checked by default
auto highestPixelsComboBox = new QComboBox(this);
highestPixelsComboBox->addItem("Show 0 highest pixels", 0);
highestPixelsComboBox->addItem("Show 1 highest pixel", 1);
highestPixelsComboBox->addItem("Show 2 highest pixels", 2);
highestPixelsComboBox->addItem("Show 3 highest pixels", 3);
highestPixelsComboBox->addItem("Show 5 highest pixels", 5);
highestPixelsComboBox->addItem("Show 10 highest pixels", 10);
highestPixelsComboBox->setCurrentIndex(0);
connect(highestPixelsComboBox, &QComboBox::currentIndexChanged, this, [this, highestPixelsComboBox](int index) {
int value = highestPixelsComboBox->itemData(index).toInt();
emit showHighestPixels(value);
});
auto saturatedPixelsCheckBox = new QCheckBox("Show saturated pixels", this);
connect(saturatedPixelsCheckBox, &QCheckBox::toggled, this, &JFJochViewerSidePanel::saturatedPixelsToggled);
auto colorSelectButton = new QPushButton("Select feature color", this);
connect(colorSelectButton, &QPushButton::clicked, this, [this]() {
QColor color = QColorDialog::getColor(Qt::magenta, this, "Select Feature Color");
if (color.isValid()) {
emit setFeatureColor(color);
}
});
auto spotColorSelectButton = new QPushButton("Select spot color", this);
connect(spotColorSelectButton, &QPushButton::clicked, this, [this]() {
QColor color = QColorDialog::getColor(Qt::green, this, "Select Spot Color");
if (color.isValid()) {
emit setSpotColor(color);
}
});
auto image_feature_grid = new QGridLayout();
image_feature_grid->addWidget(spotToggleCheckBox, 0, 0);
image_feature_grid->addWidget(highlightIceRingToggleCheckBox, 0, 1);
image_feature_grid->addWidget(predictionsToggleCheckBox, 1, 0);
image_feature_grid->addWidget(resRingsCheckBox, 2, 0);
image_feature_grid->addWidget(autoResRingsCheckBox, 2, 1);
image_feature_grid->addWidget(res_rings_edit, 3, 0, 1, 2);
image_feature_grid->addWidget(saturatedPixelsCheckBox, 4, 0);
image_feature_grid->addWidget(highestPixelsComboBox, 4, 1);
image_feature_grid->addWidget(colorSelectButton, 5, 0);
image_feature_grid->addWidget(spotColorSelectButton, 5, 1);
layout->addLayout(image_feature_grid);
connect(autoResRingsCheckBox, &QCheckBox::toggled, this, &JFJochViewerSidePanel::enableAutoResRings);
connect(res_rings_edit, &QLineEdit::editingFinished,
this, &JFJochViewerSidePanel::editingFinished);
connect(resRingsCheckBox, &QCheckBox::toggled,
this, &JFJochViewerSidePanel::enableResRings);
layout->addWidget(new TitleLabel("Image statistics plot", this));
chart = new JFJochViewerSidePanelChart(this);
layout->addWidget(chart);
connect(this, &JFJochViewerSidePanel::imageLoaded,
chart, &JFJochViewerSidePanelChart::loadImage);
layout->addWidget(new TitleLabel("ROI", this));
roi = new JFJochViewerImageROIStatistics(this);
@@ -42,96 +134,7 @@ JFJochViewerSidePanel::JFJochViewerSidePanel(QWidget *parent) : QWidget(parent)
connect(roi, &JFJochViewerImageROIStatistics::AddROIToUserMask, [this]() { emit AddROIToUserMask(); });
connect(roi, &JFJochViewerImageROIStatistics::SubtractROIFromUserMask, [this]() { emit SubtractROIFromUserMask(); });
layout->addWidget(new TitleLabel("Image features", this));
auto spotToggleCheckBox = new QCheckBox("Show spots", this);
spotToggleCheckBox->setCheckState(Qt::CheckState::Checked);
layout->addWidget(spotToggleCheckBox); // Add checkbox to the grid layout
connect(spotToggleCheckBox, &QCheckBox::toggled, this, &JFJochViewerSidePanel::spotsToggled);
auto highlightIceRingToggleCheckBox = new QCheckBox("Highlight spots on ice rings", this);
highlightIceRingToggleCheckBox->setCheckState(Qt::CheckState::Checked);
layout->addWidget(highlightIceRingToggleCheckBox);
connect(highlightIceRingToggleCheckBox, &QCheckBox::toggled, this,&JFJochViewerSidePanel::highlightIceRingsToggled);
auto predictionsToggleCheckBox = new QCheckBox("Show predictions", this);
predictionsToggleCheckBox->setCheckState(Qt::CheckState::Unchecked);
layout->addWidget(predictionsToggleCheckBox); // Add checkbox to the grid layout
connect(predictionsToggleCheckBox, &QCheckBox::toggled, this,
&JFJochViewerSidePanel::predictionsToggled);
resRingsCheckBox = new QCheckBox("Show resolution rings", this);
resRingsCheckBox->setCheckState(Qt::Unchecked);
layout->addWidget(resRingsCheckBox);
autoResRingsCheckBox = new QCheckBox("Resolution rings auto.", this);
res_rings_edit = new QLineEdit(this);
res_rings_edit->setPlaceholderText("Enter non-negative floats, e.g., 1.0,2.5,3.7");
res_rings_edit->setEnabled(false); // Initially disabled as "Auto Res Rings" is checked by default
layout->addWidget(autoResRingsCheckBox); // Add the checkbox to the grid layout
layout->addWidget(res_rings_edit); // Add the line edit to the grid layout
auto highestPixelsComboBox = new QComboBox(this);
highestPixelsComboBox->addItem("0 highest pixels", 0);
highestPixelsComboBox->addItem("1 highest pixel", 1);
highestPixelsComboBox->addItem("2 highest pixels", 2);
highestPixelsComboBox->addItem("3 highest pixels", 3);
highestPixelsComboBox->addItem("5 highest pixels", 5);
highestPixelsComboBox->addItem("10 highest pixels", 10);
highestPixelsComboBox->setCurrentIndex(0);
layout->addWidget(highestPixelsComboBox);
connect(highestPixelsComboBox, &QComboBox::currentIndexChanged, this, [this, highestPixelsComboBox](int index) {
int value = highestPixelsComboBox->itemData(index).toInt();
emit showHighestPixels(value);
});
auto saturatedPixelsCheckBox = new QCheckBox("Show saturated pixels", this);
layout->addWidget(saturatedPixelsCheckBox);
connect(saturatedPixelsCheckBox, &QCheckBox::toggled, this, &JFJochViewerSidePanel::saturatedPixelsToggled);
auto colorSelectButton = new QPushButton("Select feature color", this);
layout->addWidget(colorSelectButton);
connect(colorSelectButton, &QPushButton::clicked, this, [this]() {
QColor color = QColorDialog::getColor(Qt::magenta, this, "Select Feature Color");
if (color.isValid()) {
emit setFeatureColor(color);
}
});
auto spotColorSelectButton = new QPushButton("Select spot color", this);
layout->addWidget(spotColorSelectButton);
connect(spotColorSelectButton, &QPushButton::clicked, this, [this]() {
QColor color = QColorDialog::getColor(Qt::green, this, "Select Spot Color");
if (color.isValid()) {
emit setSpotColor(color);
}
});
connect(autoResRingsCheckBox, &QCheckBox::toggled, this, &JFJochViewerSidePanel::enableAutoResRings);
connect(res_rings_edit, &QLineEdit::editingFinished,
this, &JFJochViewerSidePanel::editingFinished);
connect(resRingsCheckBox, &QCheckBox::toggled,
this, &JFJochViewerSidePanel::enableResRings);
layout->addWidget(new TitleLabel("Image statistics plot", this));
chart = new JFJochViewerSidePanelChart(this);
layout->addWidget(chart);
connect(this, &JFJochViewerSidePanel::imageLoaded,
chart, &JFJochViewerSidePanelChart::loadImage);
layout->addWidget(new TitleLabel("Data analysis (experimental)", this));
layout->addWidget(new TitleLabel("Data analysis", this));
auto analyzeButton = new QPushButton("Full analysis", this);
connect(analyzeButton, &QPushButton::clicked,[this] {emit analyze();});
@@ -141,16 +144,13 @@ JFJochViewerSidePanel::JFJochViewerSidePanel(QWidget *parent) : QWidget(parent)
layout->addWidget(new TitleLabel("Powder geometry calibration", this));
calibrantCombo = new QComboBox(this);
layout->addWidget(calibrantCombo);
updateCalibrantList();
auto findBeamCenterButton = new QPushButton("Guess detector calibration", this);
connect(findBeamCenterButton, &QPushButton::clicked,this, &JFJochViewerSidePanel::findBeamCenterClicked);
layout->addWidget(findBeamCenterButton);
auto optimizeBeamCenterButton = new QPushButton("Refine detector calibration", this);
connect(optimizeBeamCenterButton, &QPushButton::clicked,this, &JFJochViewerSidePanel::optimizeBeamCenterClicked);
layout->addWidget(optimizeBeamCenterButton);
// Add preset ice rings button below LaB6 calibration
auto iceRingsButton = new QPushButton("Display ice rings", this);
@@ -159,7 +159,17 @@ JFJochViewerSidePanel::JFJochViewerSidePanel(QWidget *parent) : QWidget(parent)
const QVector<float> ice_rings(ICE_RING_RES_A.begin(), ICE_RING_RES_A.end());
setRings(ice_rings);
});
layout->addWidget(iceRingsButton);
auto refine_row = new QGridLayout();
refine_row->setSpacing(12);
refine_row->addWidget(new QLabel("Calibrant:"),0,0);
refine_row->addWidget(calibrantCombo,0,1);
refine_row->addWidget(findBeamCenterButton,1, 0);
refine_row->addWidget(optimizeBeamCenterButton,1, 1);
refine_row->addWidget(iceRingsButton,2, 0,1,2);
layout->addLayout(refine_row);
layout->addStretch();
setLayout(layout); // Set the layout to the widget