Files
Jungfraujoch/viewer/windows/JFJochAzIntWindow.cpp
Filip Leonarski 808691251e
All checks were successful
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 11m48s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 12m18s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 12m18s
Build Packages / build:rpm (rocky8) (push) Successful in 11m43s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 12m31s
Build Packages / Unit tests (push) Has been skipped
Build Packages / Generate python client (push) Successful in 17s
Build Packages / Create release (push) Has been skipped
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 13m2s
Build Packages / Build documentation (push) Successful in 37s
Build Packages / build:rpm (rocky9) (push) Successful in 9m45s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 6m35s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 7m8s
v1.0.0-rc.101 (#6)
This is an UNSTABLE release.

* jfjoch_viewer: Auto load is better handling change of states
* jfjoch_viewer: Fix DBus registration
* jfjoch_viewer: Handle charts better with vertical lines on hover and status bar update
* jfjoch_viewer: Calculate ROI in a more efficient way

Reviewed-on: #6
Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch>
Co-committed-by: Filip Leonarski <filip.leonarski@psi.ch>
2025-11-16 12:35:00 +01:00

171 lines
5.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#include "JFJochAzIntWindow.h"
#include <QGroupBox>
#include <QButtonGroup>
#include <QFormLayout>
JFJochAzIntWindow::JFJochAzIntWindow(
const AzimuthalIntegrationSettings &settings,
QWidget *parent)
: JFJochHelperWindow(parent),
m_settings(settings)
{
setWindowTitle("Azimuthal integration settings");
QWidget *centralWidget = new QWidget(this);
setCentralWidget(centralWidget);
auto mainLayout = new QVBoxLayout(centralWidget);
// Group box similar to TS Paper + stacked inputs
auto group = new QGroupBox("Azimuthal integration", this);
auto formLayout = new QFormLayout(group);
// Q spacing
m_qSpacing = new SliderPlusBox(0.01, 1.0, 0.001, 3, this);
m_qSpacing->setValue(m_settings.GetQSpacing_recipA());
formLayout->addRow(tr("Q spacing [Å⁻¹]:"), m_qSpacing);
// Low Q
m_lowQ = new SliderPlusBox(0.001, 10.0, 0.001, 3, this);
m_lowQ->setValue(m_settings.GetLowQ_recipA());
formLayout->addRow(tr("Low Q [Å⁻¹]:"), m_lowQ);
// High Q
m_highQ = new SliderPlusBox(0.001, 10.0, 0.001, 3, this);
m_highQ->setValue(m_settings.GetHighQ_recipA());
formLayout->addRow(tr("High Q [Å⁻¹]:"), m_highQ);
// Solid angle / polarization correction checkboxes
m_solidAngleCheckBox = new QCheckBox(tr("Solid angle correction"), this);
m_solidAngleCheckBox->setChecked(m_settings.IsSolidAngleCorrection());
formLayout->addRow(QString(), m_solidAngleCheckBox);
m_polarizationCheckBox = new QCheckBox(tr("Polarization correction"), this);
m_polarizationCheckBox->setChecked(m_settings.IsPolarizationCorrection());
formLayout->addRow(QString(), m_polarizationCheckBox);
// Azimuthal bins (radio buttons like TS frontend)
auto azimGroupBox = new QGroupBox(tr("Azimuthal bins"), this);
auto azimLayout = new QHBoxLayout(azimGroupBox);
m_azimuthalBinsGroup = new QButtonGroup(this);
const QList<int> binOptions = {1, 2, 4, 8, 16, 32, 64, 128};
const int currentBins = m_settings.GetAzimuthalBinCount();
for (int bins : binOptions) {
auto *btn = new QRadioButton(QString::number(bins), azimGroupBox);
m_azimuthalBinsGroup->addButton(btn, bins);
m_azimuthalBinButtons.push_back(btn);
azimLayout->addWidget(btn);
if (bins == currentBins) {
btn->setChecked(true);
}
}
group->setLayout(formLayout);
mainLayout->addWidget(group);
mainLayout->addWidget(azimGroupBox);
// Error label at bottom (no buttons)
m_errorLabel = new QLabel(this);
m_errorLabel->setStyleSheet("color: rgb(200, 0, 0);"); // red-ish text for errors
m_errorLabel->setWordWrap(true);
mainLayout->addWidget(m_errorLabel);
// Connections on change, update errors, settings, and emit
connect(m_qSpacing, &SliderPlusBox::valueChanged, [this](double val) {
m_qSpacingError = (val < 0.01);
Update();
});
connect(m_lowQ, &SliderPlusBox::valueChanged, [this](double val) {
m_lowQError = (val < 0.001 || val > 10.0);
Update();
});
connect(m_highQ, &SliderPlusBox::valueChanged, [this](double val) {
m_highQError = (val < 0.001 || val > 10.0);
Update();
});
connect(m_solidAngleCheckBox, &QCheckBox::toggled, [this](bool /*checked*/) {
Update();
});
connect(m_polarizationCheckBox, &QCheckBox::toggled, [this](bool /*checked*/) {
Update();
});
connect(m_azimuthalBinsGroup,
QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked),
[this](QAbstractButton * /*btn*/) {
Update();
});
Update();
}
void JFJochAzIntWindow::UpdateErrorLabel() {
const double lowQ = m_lowQ->value();
const double highQ = m_highQ->value();
QStringList messages;
if (m_qSpacingError) {
messages << tr("Q spacing must be ≥ 0.01 Å⁻¹.");
}
if (m_lowQError) {
messages << tr("Low Q must be between 0.001 and 10 Å⁻¹.");
}
if (m_highQError) {
messages << tr("High Q must be between 0.001 and 10 Å⁻¹.");
}
if (highQ <= lowQ) {
messages << tr("High Q must be greater than Low Q.");
}
if (messages.isEmpty()) {
m_errorLabel->clear();
} else {
m_errorLabel->setText(messages.join(' '));
}
}
void JFJochAzIntWindow::ApplyToSettings() {
const float lowQ = static_cast<float>(m_lowQ->value());
const float highQ = static_cast<float>(m_highQ->value());
const float qSpacing = static_cast<float>(m_qSpacing->value());
m_settings.SolidAngleCorrection(m_solidAngleCheckBox->isChecked());
m_settings.PolarizationCorrection(m_polarizationCheckBox->isChecked());
m_settings.QRange_recipA(lowQ, highQ);
m_settings.QSpacing_recipA(qSpacing);
const int bins = m_azimuthalBinsGroup->checkedId();
if (bins > 0) {
m_settings.AzimuthalBinCount(bins);
}
}
void JFJochAzIntWindow::Update() {
// Update error label first
UpdateErrorLabel();
// If there are validation errors, do not update settings / emit
const double lowQ = m_lowQ->value();
const double highQ = m_highQ->value();
const bool rangeError = (highQ <= lowQ);
const bool anyError = m_lowQError || m_highQError || m_qSpacingError || rangeError;
if (anyError)
return;
// Update internal settings from widgets
ApplyToSettings();
// Emit updated settings when valid
emit settingsChanged(m_settings);
}