Files
Jungfraujoch/viewer/windows/JFJochAzIntWindow.cpp
T
leonarski_f c49bd2ac3b
Build Packages / XDS test (neggia plugin) (push) Successful in 6m2s
Build Packages / Unit tests (push) Successful in 1h37m1s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 12m4s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 13m30s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 12m52s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 11m53s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 12m38s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 13m30s
Build Packages / build:rpm (rocky8) (push) Successful in 10m47s
Build Packages / build:rpm (rocky9) (push) Successful in 11m48s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 10m40s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 9m44s
Build Packages / DIALS test (push) Successful in 12m59s
Build Packages / XDS test (durin plugin) (push) Successful in 8m33s
Build Packages / Generate python client (push) Successful in 16s
Build Packages / XDS test (JFJoch plugin) (push) Successful in 6m24s
Build Packages / Build documentation (push) Successful in 57s
Build Packages / Create release (push) Skipped
v1.0.0-rc.152 (#62)
* jfjoch_broker: Fix bounds for azimuthal integration for Q spacing (allow Q of 1e-5)
* jfjoch_viewer: Adjust Q bounds for azimuthal integration
* jfjoch_azint: Add tool to do quick azimuthal integration

Reviewed-on: #62
2026-06-17 20:36:24 +02:00

173 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>
#include "../widgets/SliderPlusBox.h"
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(1e-5, 1.0, 0.001, 5, this, SliderPlusBox::ScaleType::Logarithmic);
m_qSpacing->setValue(m_settings.GetQSpacing_recipA());
formLayout->addRow(tr("Q spacing [Å⁻¹]:"), m_qSpacing);
// Low Q
m_lowQ = new SliderPlusBox(1e-5, 10.0, 0.001, 4, this);
m_lowQ->setValue(m_settings.GetLowQ_recipA());
formLayout->addRow(tr("Low Q [Å⁻¹]:"), m_lowQ);
// High Q
m_highQ = new SliderPlusBox(2e-5, 10.0, 0.001, 4, 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 < 1e-5);
Update();
});
connect(m_lowQ, &SliderPlusBox::valueChanged, [this](double val) {
m_lowQError = (val < 1e-5 || val > 10.0);
Update();
});
connect(m_highQ, &SliderPlusBox::valueChanged, [this](double val) {
m_highQError = (val < 2e-5 || 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 ≥ 1e-5 Å⁻¹.");
}
if (m_lowQError) {
messages << tr("Low Q must be between 1e-5 and 10 Å⁻¹.");
}
if (m_highQError) {
messages << tr("High Q must be between 2e-5 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);
}