diff --git a/GUI/View/Instrument/DepthProbeInstrumentEditor.cpp b/GUI/View/Instrument/DepthProbeInstrumentEditor.cpp index 34aadc7d68fd7167e14a64e1883750dbf8522031..54c41ecb6dd514d9b1f287ee9bae0581185852a5 100644 --- a/GUI/View/Instrument/DepthProbeInstrumentEditor.cpp +++ b/GUI/View/Instrument/DepthProbeInstrumentEditor.cpp @@ -37,13 +37,9 @@ DepthProbeInstrumentEditor::DepthProbeInstrumentEditor(QWidget* parent, auto* vLayout = new QVBoxLayout(parametersGroupBox); vLayout->setContentsMargins(30, 8, 0, 0); - // valid input range is ]0,inf[ - MeanConfig wave_cfg{boost::numeric::interval<double>(std::numeric_limits<double>::min(), - std::numeric_limits<double>::max()), - 4, true}; auto* m_wavelengthEditor = - new DistributionEditor("Wavelength [nm]", wave_cfg, GUI::ID::Distributions::Symmetric, this, - instrument->beamItem()->wavelengthItem()); + new DistributionEditor("Wavelength", MeanConfig{true}, GUI::ID::Distributions::Symmetric, + this, instrument->beamItem()->wavelengthItem()); vLayout->addWidget(m_wavelengthEditor); auto* inclinationEditor = diff --git a/GUI/View/Instrument/DistributionEditor.cpp b/GUI/View/Instrument/DistributionEditor.cpp index f7cc2e5567aa1f0808fd8c64cf18a4be9e7c161b..e2494e48c64acb25e512b28f32dd1415496445f0 100644 --- a/GUI/View/Instrument/DistributionEditor.cpp +++ b/GUI/View/Instrument/DistributionEditor.cpp @@ -151,11 +151,6 @@ BeamDistributionItem* DistributionSelector::item() const return m_item; } -const std::optional<MeanConfig>& DistributionSelector::meanConfig() const -{ - return m_meanConfig; -} - GUI::ID::Distributions DistributionSelector::distributions() const { return m_distributions; diff --git a/GUI/View/Instrument/DistributionEditor.h b/GUI/View/Instrument/DistributionEditor.h index 5192ea54e080c21e0e5b197ad2a1be5691da813b..edd62d2c258f85ba908aea1ea0fc0da70678b977 100644 --- a/GUI/View/Instrument/DistributionEditor.h +++ b/GUI/View/Instrument/DistributionEditor.h @@ -35,11 +35,9 @@ class UIntDescriptor; #include <map> #include <optional> -/// configuration to control how the user can enter a mean value +//! configuration to control how the user can enter a mean value struct MeanConfig { - boost::numeric::interval<double> range; // range for the mean value - int decimals; // number of decimals shown in the input - bool scientific; // whether to use a scientific number notation + bool scientific; //!< whether to use a scientific number notation }; /// Widget for selecting a distribution (combo box) and input of the corresponding values @@ -60,7 +58,6 @@ public: BeamDistributionItem* item); BeamDistributionItem* item() const; - const std::optional<MeanConfig>& meanConfig() const; GUI::ID::Distributions distributions() const; void refresh(); diff --git a/GUI/View/Instrument/DistributionForms.cpp b/GUI/View/Instrument/DistributionForms.cpp deleted file mode 100644 index 2673a0301f08447a4cc4a3fe85b74f3319229ab8..0000000000000000000000000000000000000000 --- a/GUI/View/Instrument/DistributionForms.cpp +++ /dev/null @@ -1,701 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file GUI/View/Instrument/DistributionForms.cpp -//! @brief Implements class InstrumentSelectorWidget -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2018 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#include "GUI/View/Instrument/DistributionForms.h" -#include "GUI/Model/Descriptor/DistributionItems.h" -#include "GUI/Model/Descriptor/DoubleDescriptor.h" -#include "GUI/View/Instrument/DistributionEditor.h" -#include "GUI/View/PropertyEditor/ScientificSpinBox.h" -#include <QDoubleSpinBox> -#include <QFormLayout> -#include <QSpinBox> - -#include <boost/polymorphic_cast.hpp> - -using boost::polymorphic_downcast; - -#include "GUI/Model/Device/BeamDistributionItem.h" -#include <boost/numeric/interval.hpp> - -using boost::numeric::interval; - -namespace { - -namespace Range { - -// constant for often used interval ]-inf,inf[ -static const interval<double> full(std::numeric_limits<double>::lowest(), - std::numeric_limits<double>::max()); - -// constant for often used interval [0,inf[ -static const interval<double> nonnegative(0, std::numeric_limits<double>::max()); - -} // namespace Range - -/// perform a strandard configuration for the QSpinBox -void configSpinBox(QSpinBox* spinbox) -{ - spinbox->setRange(1, std::numeric_limits<int>::max()); -} - -/// configure the given QDoubleSpinBox -void configSpinBox(QDoubleSpinBox* spinbox, const interval<double>& range, int decimals = 3) -{ - spinbox->setRange(range.lower(), range.upper()); - spinbox->setDecimals(decimals); - spinbox->setSingleStep(0.01); -} - -/// configure the given ScientificSpinBox -void configSpinBox(ScientificSpinBox* spinbox, const interval<double>& range, int decimals) -{ - spinbox->setMinimum(range.lower()); - spinbox->setMaximum(range.upper()); - spinbox->setDecimals(decimals); - spinbox->setSingleStep(0.01); -} - -/// visitor to set the value of the spin box -struct set_value_visitor { - double value; - - set_value_visitor(double val) - : value(val) - { - } - void operator()(QDoubleSpinBox* spinbox) const - { - if (spinbox) - spinbox->setValue(value); - } - void operator()(ScientificSpinBox* spinbox) const { spinbox->setValue(value); } -}; - -/// visitor to get the widget from the variant -struct widget_visitor { - QWidget* operator()(QDoubleSpinBox* spinbox) { return spinbox; } - QWidget* operator()(ScientificSpinBox* spinbox) { return spinbox; } -}; - -/// visitor to configure the actual spinbox -struct config_visitor { - const interval<double>& range; - int decimals; - - config_visitor(const interval<double>& r, int d) - : range(r) - , decimals(d) - { - } - void operator()(QDoubleSpinBox* spinbox) { configSpinBox(spinbox, range, decimals); } - void operator()(ScientificSpinBox* spinbox) { configSpinBox(spinbox, range, decimals); } -}; - -} // namespace - -//================================================================================================== -// DistributionForm -//================================================================================================== -//-------------------------------------------------------------------------------------------------- -// protected member functions -//-------------------------------------------------------------------------------------------------- - -DistributionForm::DistributionForm(QWidget* parent, Qt::WindowFlags f) - : QWidget(parent, f) -{ -} - -//================================================================================================== -// CosineDistributionForm -//================================================================================================== -//-------------------------------------------------------------------------------------------------- -// public member functions -//-------------------------------------------------------------------------------------------------- - -CosineDistributionForm::CosineDistributionForm(const std::optional<MeanConfig>& mean_config, - QWidget* parent, Qt::WindowFlags f) - : DistributionForm(parent, f) - , m_item(nullptr) -{ - auto* layout = new QFormLayout(this); - layout->setMargin(0); - - if (mean_config) { - if (mean_config->scientific) { - auto* spinbox = new ScientificSpinBox(this); - connect(spinbox, &ScientificSpinBox::valueChanged, this, - &CosineDistributionForm::onMeanChanged); - m_meanSpinBox = spinbox; - } else { - auto* spinbox = new QDoubleSpinBox(this); - connect(spinbox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, - &CosineDistributionForm::onMeanChanged); - m_meanSpinBox = spinbox; - } - std::visit(config_visitor(mean_config->range, mean_config->decimals), m_meanSpinBox); - layout->addRow(u8"Mean (\u03bc):", std::visit(widget_visitor(), m_meanSpinBox)); - } else - m_meanSpinBox.emplace<0>(nullptr); - - m_sigmaSpinBox = new QDoubleSpinBox(this); - configSpinBox(m_sigmaSpinBox, Range::nonnegative); - connect(m_sigmaSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, - &CosineDistributionForm::onSigmaChanged); - layout->addRow(u8"Standard deviation (\u03c3):", m_sigmaSpinBox); - - m_samplesSpinBox = new QSpinBox(this); - configSpinBox(m_samplesSpinBox); - connect(m_samplesSpinBox, qOverload<int>(&QSpinBox::valueChanged), this, - &CosineDistributionForm::onSamplesChanged); - layout->addRow("Number of samples:", m_samplesSpinBox); - - m_sigmaFactorSpinBox = new QDoubleSpinBox(this); - configSpinBox(m_sigmaFactorSpinBox, Range::nonnegative); - connect(m_sigmaFactorSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, - &CosineDistributionForm::onSigmaFactorChanged); - layout->addRow(u8"\u03c3 factor:", m_sigmaFactorSpinBox); -} - -void CosineDistributionForm::setupDistribution(BeamDistributionItem* item) -{ - if (!item->distribution()->is<DistributionCosineItem>()) - item->setDistributionType<DistributionCosineItem>(); - m_item = polymorphic_downcast<DistributionCosineItem*>(item->distribution()); - - std::visit(set_value_visitor(m_item->mean()), m_meanSpinBox); - m_sigmaSpinBox->setValue(m_item->sigma()); - m_samplesSpinBox->setValue(static_cast<int>(m_item->numberOfSamples())); - m_samplesSpinBox->setMinimum(1); - m_sigmaFactorSpinBox->setValue(m_item->sigmaFactor()); -} - -//-------------------------------------------------------------------------------------------------- -// private slots -//-------------------------------------------------------------------------------------------------- - -void CosineDistributionForm::onMeanChanged(double value) -{ - m_item->setMean(value); - emit distributionChanged(); -} - -void CosineDistributionForm::onSigmaChanged(double value) -{ - m_item->setSigma(value); - emit distributionChanged(); -} - -void CosineDistributionForm::onSamplesChanged(int value) -{ - auto samples = static_cast<size_t>(value); - m_item->setNumberOfSamples(samples); - emit distributionChanged(); -} - -void CosineDistributionForm::onSigmaFactorChanged(double value) -{ - m_item->setSigmaFactor(value); - emit distributionChanged(); -} - -//================================================================================================== -// GateDistributionForm -//================================================================================================== -//-------------------------------------------------------------------------------------------------- -// public member functions -//-------------------------------------------------------------------------------------------------- - -GateDistributionForm::GateDistributionForm(QWidget* parent, Qt::WindowFlags f) - : DistributionForm(parent, f) - , m_item(nullptr) -{ - auto* layout = new QFormLayout(this); - layout->setMargin(0); - - m_minimumSpinBox = new QDoubleSpinBox(this); - configSpinBox(m_minimumSpinBox, Range::full); - connect(m_minimumSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, - &GateDistributionForm::onMinimumChanged); - layout->addRow("Minimum:", m_minimumSpinBox); - - m_maximumSpinBox = new QDoubleSpinBox(this); - configSpinBox(m_maximumSpinBox, Range::full); - connect(m_maximumSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, - &GateDistributionForm::onMaximumChanged); - layout->addRow("Maximum:", m_maximumSpinBox); - - m_samplesSpinBox = new QSpinBox(this); - configSpinBox(m_samplesSpinBox); - connect(m_samplesSpinBox, qOverload<int>(&QSpinBox::valueChanged), this, - &GateDistributionForm::onSamplesChanged); - layout->addRow("Number of samples:", m_samplesSpinBox); -} - -void GateDistributionForm::setupDistribution(BeamDistributionItem* item) -{ - if (!item->distribution()->is<DistributionGateItem>()) - item->setDistributionType<DistributionGateItem>(); - m_item = polymorphic_downcast<DistributionGateItem*>(item->distribution()); - - m_minimumSpinBox->setValue(m_item->minimum()); - m_maximumSpinBox->setValue(m_item->maximum()); - m_samplesSpinBox->setValue(static_cast<int>(m_item->numberOfSamples())); -} - -//-------------------------------------------------------------------------------------------------- -// private slots -//-------------------------------------------------------------------------------------------------- - -void GateDistributionForm::onMinimumChanged(double value) -{ - double maximum = m_item->maximum(); - if (maximum < value) { - m_item->setRange(value, value); - m_maximumSpinBox->setValue(value); - } else { - m_item->setRange(value, maximum); - emit distributionChanged(); - } -} - -void GateDistributionForm::onMaximumChanged(double value) -{ - double minimum = m_item->minimum(); - if (minimum > value) { - m_item->setRange(value, value); - m_minimumSpinBox->setValue(value); - } else { - m_item->setRange(minimum, value); - emit distributionChanged(); - } -} - -void GateDistributionForm::onSamplesChanged(int value) -{ - auto samples = static_cast<size_t>(value); - m_item->setNumberOfSamples(samples); - emit distributionChanged(); -} - -//================================================================================================== -// GaussDistributionForm -//================================================================================================== -//-------------------------------------------------------------------------------------------------- -// public member functions -//-------------------------------------------------------------------------------------------------- - -GaussDistributionForm::GaussDistributionForm(const std::optional<MeanConfig>& mean_config, - QWidget* parent, Qt::WindowFlags f) - : DistributionForm(parent, f) - , m_item(nullptr) -{ - auto* layout = new QFormLayout(this); - layout->setMargin(0); - - if (mean_config) { - if (mean_config->scientific) { - auto* spinbox = new ScientificSpinBox(this); - connect(spinbox, &ScientificSpinBox::valueChanged, this, - &GaussDistributionForm::onMeanChanged); - m_meanSpinBox = spinbox; - } else { - auto* spinbox = new QDoubleSpinBox(this); - connect(spinbox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, - &GaussDistributionForm::onMeanChanged); - - m_meanSpinBox = spinbox; - } - std::visit(config_visitor(mean_config->range, mean_config->decimals), m_meanSpinBox); - layout->addRow(u8"Mean (\u03bc):", std::visit(widget_visitor(), m_meanSpinBox)); - } else - m_meanSpinBox.emplace<0>(nullptr); - - m_stdDevSpinBox = new QDoubleSpinBox(this); - configSpinBox(m_stdDevSpinBox, Range::nonnegative); - connect(m_stdDevSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, - &GaussDistributionForm::onDeviationChanged); - layout->addRow(u8"Standard deviation (\u03c3):", m_stdDevSpinBox); - - m_samplesSpinBox = new QSpinBox(this); - configSpinBox(m_samplesSpinBox); - connect(m_samplesSpinBox, qOverload<int>(&QSpinBox::valueChanged), this, - &GaussDistributionForm::onSamplesChanged); - layout->addRow("Number of samples:", m_samplesSpinBox); - - m_sigmaFactorSpinBox = new QDoubleSpinBox(this); - configSpinBox(m_sigmaFactorSpinBox, Range::nonnegative); - connect(m_sigmaFactorSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, - &GaussDistributionForm::onSigmaFactorChanged); - layout->addRow(u8"\u03c3 factor:", m_sigmaFactorSpinBox); -} - -void GaussDistributionForm::setupDistribution(BeamDistributionItem* item) -{ - if (!item->distribution()->is<DistributionGaussianItem>()) - item->setDistributionType<DistributionGaussianItem>(); - m_item = polymorphic_downcast<DistributionGaussianItem*>(item->distribution()); - - std::visit(set_value_visitor(m_item->mean()), m_meanSpinBox); - m_stdDevSpinBox->setValue(m_item->standardDeviation()); - m_samplesSpinBox->setValue(static_cast<int>(m_item->numberOfSamples())); - m_sigmaFactorSpinBox->setValue(m_item->sigmaFactor()); -} - -//-------------------------------------------------------------------------------------------------- -// private slots -//-------------------------------------------------------------------------------------------------- - -void GaussDistributionForm::onMeanChanged(double value) -{ - m_item->setMean(value); - emit distributionChanged(); -} - -void GaussDistributionForm::onDeviationChanged(double value) -{ - m_item->setStandardDeviation(value); - emit distributionChanged(); -} - -void GaussDistributionForm::onSamplesChanged(int value) -{ - auto samples = static_cast<size_t>(value); - m_item->setNumberOfSamples(samples); - emit distributionChanged(); -} - -void GaussDistributionForm::onSigmaFactorChanged(double value) -{ - m_item->setSigmaFactor(value); - emit distributionChanged(); -} - -//================================================================================================== -// LogNormalDistributionForm -//================================================================================================== -//-------------------------------------------------------------------------------------------------- -// public member functions -//-------------------------------------------------------------------------------------------------- - -LogNormalDistributionForm::LogNormalDistributionForm(QWidget* parent, Qt::WindowFlags f) - : DistributionForm(parent, f) - , m_item(nullptr) -{ - auto* layout = new QFormLayout(this); - layout->setMargin(0); - - m_medianSpinBox = new QDoubleSpinBox(this); - configSpinBox(m_medianSpinBox, Range::nonnegative); - connect(m_medianSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, - &LogNormalDistributionForm::onMedianChanged); - layout->addRow("Median:", m_medianSpinBox); - - m_scaleSpinBox = new QDoubleSpinBox(this); - configSpinBox(m_scaleSpinBox, Range::nonnegative); - connect(m_scaleSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, - &LogNormalDistributionForm::onScaleChanged); - layout->addRow("Scale parameter:", m_scaleSpinBox); - - m_samplesSpinBox = new QSpinBox(this); - configSpinBox(m_samplesSpinBox); - connect(m_samplesSpinBox, qOverload<int>(&QSpinBox::valueChanged), this, - &LogNormalDistributionForm::onSamplesChanged); - layout->addRow("Number of samples:", m_samplesSpinBox); - - m_sigmaFactorSpinBox = new QDoubleSpinBox(this); - configSpinBox(m_sigmaFactorSpinBox, Range::nonnegative); - connect(m_sigmaFactorSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, - &LogNormalDistributionForm::onSigmaFactorChanged); - layout->addRow(u8"\u03c3 factor:", m_sigmaFactorSpinBox); -} - -void LogNormalDistributionForm::setupDistribution(BeamDistributionItem* item) -{ - if (!item->distribution()->is<DistributionLogNormalItem>()) - item->setDistributionType<DistributionLogNormalItem>(); - m_item = polymorphic_downcast<DistributionLogNormalItem*>(item->distribution()); - - m_medianSpinBox->setValue(m_item->median()); - m_scaleSpinBox->setValue(m_item->scaleParameter()); - m_samplesSpinBox->setValue(static_cast<int>(m_item->numberOfSamples())); - m_sigmaFactorSpinBox->setValue(m_item->sigmaFactor()); -} - -//-------------------------------------------------------------------------------------------------- -// private slots -//-------------------------------------------------------------------------------------------------- - -void LogNormalDistributionForm::onMedianChanged(double value) -{ - m_item->setMedian(value); - emit distributionChanged(); -} - -void LogNormalDistributionForm::onScaleChanged(double value) -{ - m_item->setScaleParameter(value); - emit distributionChanged(); -} - -void LogNormalDistributionForm::onSamplesChanged(int value) -{ - auto samples = static_cast<size_t>(value); - m_item->setNumberOfSamples(samples); - emit distributionChanged(); -} - -void LogNormalDistributionForm::onSigmaFactorChanged(double value) -{ - m_item->setSigmaFactor(value); - emit distributionChanged(); -} - -//================================================================================================== -// LorentzDistributionForm -//================================================================================================== -//-------------------------------------------------------------------------------------------------- -// public member functions -//-------------------------------------------------------------------------------------------------- - -LorentzDistributionForm::LorentzDistributionForm(const std::optional<MeanConfig>& mean_config, - QWidget* parent, Qt::WindowFlags f) - : DistributionForm(parent, f) - , m_item(nullptr) -{ - auto* layout = new QFormLayout(this); - layout->setMargin(0); - - if (mean_config) { - if (mean_config->scientific) { - auto* spinbox = new ScientificSpinBox(this); - connect(spinbox, &ScientificSpinBox::valueChanged, this, - &LorentzDistributionForm::onMeanChanged); - m_meanSpinBox = spinbox; - } else { - auto* spinbox = new QDoubleSpinBox(this); - connect(spinbox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, - &LorentzDistributionForm::onMeanChanged); - m_meanSpinBox = spinbox; - } - std::visit(config_visitor(mean_config->range, mean_config->decimals), m_meanSpinBox); - layout->addRow(u8"Mean (\u03bc):", std::visit(widget_visitor(), m_meanSpinBox)); - } else - m_meanSpinBox.emplace<0>(nullptr); - - m_hwhmSpinBox = new QDoubleSpinBox(this); - configSpinBox(m_hwhmSpinBox, Range::nonnegative); - connect(m_hwhmSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, - &LorentzDistributionForm::onHWHMChanged); - layout->addRow("HWHM:", m_hwhmSpinBox); - - m_samplesSpinBox = new QSpinBox(this); - configSpinBox(m_samplesSpinBox); - connect(m_samplesSpinBox, qOverload<int>(&QSpinBox::valueChanged), this, - &LorentzDistributionForm::onSamplesChanged); - layout->addRow("Number of samples:", m_samplesSpinBox); - - m_sigmaFactorSpinBox = new QDoubleSpinBox(this); - configSpinBox(m_sigmaFactorSpinBox, Range::nonnegative); - connect(m_sigmaFactorSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, - &LorentzDistributionForm::onSigmaFactorChanged); - layout->addRow(u8"\u03c3 factor:", m_sigmaFactorSpinBox); -} - -void LorentzDistributionForm::setupDistribution(BeamDistributionItem* item) -{ - if (!item->distribution()->is<DistributionLorentzItem>()) - item->setDistributionType<DistributionLorentzItem>(); - m_item = polymorphic_downcast<DistributionLorentzItem*>(item->distribution()); - - std::visit(set_value_visitor(m_item->mean()), m_meanSpinBox); - m_hwhmSpinBox->setValue(m_item->hwhm()); - m_samplesSpinBox->setValue(static_cast<int>(m_item->numberOfSamples())); - m_sigmaFactorSpinBox->setValue(m_item->sigmaFactor()); -} - -//-------------------------------------------------------------------------------------------------- -// private slots -//-------------------------------------------------------------------------------------------------- - -void LorentzDistributionForm::onMeanChanged(double value) -{ - m_item->setMean(value); - emit distributionChanged(); -} - -void LorentzDistributionForm::onHWHMChanged(double value) -{ - m_item->setHwhm(value); - emit distributionChanged(); -} - -void LorentzDistributionForm::onSamplesChanged(int value) -{ - auto samples = static_cast<size_t>(value); - m_item->setNumberOfSamples(samples); - emit distributionChanged(); -} - -void LorentzDistributionForm::onSigmaFactorChanged(double value) -{ - m_item->setSigmaFactor(value); - emit distributionChanged(); -} - -//================================================================================================== -// NoneDistributionForm -//================================================================================================== -//-------------------------------------------------------------------------------------------------- -// public member functions -//-------------------------------------------------------------------------------------------------- - -NoneDistributionForm::NoneDistributionForm(const std::optional<MeanConfig>& mean_config, - QWidget* parent, Qt::WindowFlags f) - : DistributionForm(parent, f) - , m_item(nullptr) -{ - auto* layout = new QFormLayout(this); - layout->setMargin(0); - - if (mean_config) { - if (mean_config->scientific) { - auto* spinbox = new ScientificSpinBox(this); - connect(spinbox, &ScientificSpinBox::valueChanged, this, - &NoneDistributionForm::onValueChanged); - m_spinBox = spinbox; - } else { - auto* spinbox = new QDoubleSpinBox(this); - connect(spinbox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, - &NoneDistributionForm::onValueChanged); - m_spinBox = spinbox; - } - std::visit(config_visitor(mean_config->range, mean_config->decimals), m_spinBox); - layout->addRow("Value:", std::visit(widget_visitor(), m_spinBox)); - } else - m_spinBox.emplace<0>(nullptr); -} - -void NoneDistributionForm::setupDistribution(BeamDistributionItem* item) -{ - if (!item->distribution()->is<DistributionNoneItem>()) - item->setDistributionType<DistributionNoneItem>(); - m_item = polymorphic_downcast<DistributionNoneItem*>(item->distribution()); - - std::visit(set_value_visitor(m_item->mean()), m_spinBox); -} - -//-------------------------------------------------------------------------------------------------- -// private slots -//-------------------------------------------------------------------------------------------------- - -void NoneDistributionForm::onValueChanged(double value) -{ - m_item->setMean(value); - emit distributionChanged(); -} - -//================================================================================================== -// TrapezoidDistributionForm -//================================================================================================== -//-------------------------------------------------------------------------------------------------- -// public member functions -//-------------------------------------------------------------------------------------------------- - -TrapezoidDistributionForm::TrapezoidDistributionForm(QWidget* parent, Qt::WindowFlags f) - : DistributionForm(parent, f) - , m_item(nullptr) -{ - auto* layout = new QFormLayout(this); - layout->setMargin(0); - - m_centerSpinBox = new QDoubleSpinBox(this); - configSpinBox(m_centerSpinBox, Range::full); - connect(m_centerSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, - &TrapezoidDistributionForm::onCenterChanged); - layout->addRow("Center:", m_centerSpinBox); - - m_leftWidthSpinBox = new QDoubleSpinBox(this); - configSpinBox(m_leftWidthSpinBox, Range::nonnegative); - m_leftWidthSpinBox->setDecimals(3); - m_leftWidthSpinBox->setSingleStep(0.01); - connect(m_leftWidthSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, - &TrapezoidDistributionForm::onLeftWidthChanged); - layout->addRow("Left width:", m_leftWidthSpinBox); - - m_middleWidthSpinBox = new QDoubleSpinBox(this); - configSpinBox(m_middleWidthSpinBox, Range::nonnegative); - connect(m_middleWidthSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, - &TrapezoidDistributionForm::onMiddleWidthChanged); - layout->addRow("Middle width:", m_middleWidthSpinBox); - - m_rightWidthSpinBox = new QDoubleSpinBox(this); - configSpinBox(m_rightWidthSpinBox, Range::nonnegative); - connect(m_rightWidthSpinBox, qOverload<double>(&QDoubleSpinBox::valueChanged), this, - &TrapezoidDistributionForm::onRightWidthChanged); - layout->addRow("Right width:", m_rightWidthSpinBox); - - m_samplesSpinBox = new QSpinBox(this); - configSpinBox(m_samplesSpinBox); - connect(m_samplesSpinBox, qOverload<int>(&QSpinBox::valueChanged), this, - &TrapezoidDistributionForm::onSamplesChanged); - layout->addRow("Number of samples:", m_samplesSpinBox); -} - -void TrapezoidDistributionForm::setupDistribution(BeamDistributionItem* item) -{ - if (!item->distribution()->is<DistributionTrapezoidItem>()) - item->setDistributionType<DistributionTrapezoidItem>(); - m_item = polymorphic_downcast<DistributionTrapezoidItem*>(item->distribution()); - - m_centerSpinBox->setValue(m_item->center()); - m_leftWidthSpinBox->setValue(m_item->leftWidth()); - m_middleWidthSpinBox->setValue(m_item->middleWidth()); - m_rightWidthSpinBox->setValue(m_item->rightWidth()); - m_samplesSpinBox->setValue(static_cast<int>(m_item->numberOfSamples())); -} - -//-------------------------------------------------------------------------------------------------- -// private slots -//-------------------------------------------------------------------------------------------------- - -void TrapezoidDistributionForm::onCenterChanged(double value) -{ - m_item->setCenter(value); - emit distributionChanged(); -} - -void TrapezoidDistributionForm::onLeftWidthChanged(double value) -{ - m_item->setLeftWidth(value); - emit distributionChanged(); -} - -void TrapezoidDistributionForm::onMiddleWidthChanged(double value) -{ - m_item->setMiddleWidth(value); - emit distributionChanged(); -} - -void TrapezoidDistributionForm::onRightWidthChanged(double value) -{ - m_item->setRightWidth(value); - emit distributionChanged(); -} - -void TrapezoidDistributionForm::onSamplesChanged(int value) -{ - auto samples = static_cast<size_t>(value); - m_item->setNumberOfSamples(samples); - emit distributionChanged(); -} diff --git a/GUI/View/Instrument/DistributionForms.h b/GUI/View/Instrument/DistributionForms.h deleted file mode 100644 index 9bdb0647d79c7e4363f8a5a63f2ad65b0a1f0c0b..0000000000000000000000000000000000000000 --- a/GUI/View/Instrument/DistributionForms.h +++ /dev/null @@ -1,198 +0,0 @@ -// ************************************************************************************************ -// -// BornAgain: simulate and fit reflection and scattering -// -//! @file GUI/View/Instrument/DistributionForms.h -//! @brief The forms for the various distributions used by DistributionSelector -//! -//! @homepage http://www.bornagainproject.org -//! @license GNU General Public License v3 or higher (see COPYING) -//! @copyright Forschungszentrum Jülich GmbH 2018 -//! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS) -// -// ************************************************************************************************ - -#ifndef BORNAGAIN_GUI_VIEW_INSTRUMENT_DISTRIBUTIONFORMS_H -#define BORNAGAIN_GUI_VIEW_INSTRUMENT_DISTRIBUTIONFORMS_H - -#include <QWidget> - -#include <optional> -#include <variant> - -struct MeanConfig; -class BeamDistributionItem; -class DistributionCosineItem; -class DistributionGateItem; -class DistributionGaussianItem; -class DistributionLogNormalItem; -class DistributionLorentzItem; -class DistributionNoneItem; -class DistributionTrapezoidItem; - -class QSpinBox; -class QDoubleSpinBox; -class ScientificSpinBox; - -class DistributionForm : public QWidget { - Q_OBJECT - -public: - /// Set type if not already the matching one and display parameters of distribution - virtual void setupDistribution(BeamDistributionItem* item) = 0; - -signals: - void distributionChanged(); - -protected: - DistributionForm(QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags()); -}; - - -class CosineDistributionForm : public DistributionForm { - Q_OBJECT - -public: - CosineDistributionForm(const std::optional<MeanConfig>& mean_config, QWidget* parent = nullptr, - Qt::WindowFlags f = Qt::WindowFlags()); - void setupDistribution(BeamDistributionItem* item) override; - -private slots: - void onMeanChanged(double value); - void onSigmaChanged(double value); - void onSamplesChanged(int value); - void onSigmaFactorChanged(double value); - -private: - std::variant<QDoubleSpinBox*, ScientificSpinBox*> m_meanSpinBox; - QDoubleSpinBox* m_sigmaSpinBox; - QSpinBox* m_samplesSpinBox; - QDoubleSpinBox* m_sigmaFactorSpinBox; - DistributionCosineItem* m_item; -}; - -class GateDistributionForm : public DistributionForm { - Q_OBJECT - -public: - GateDistributionForm(QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags()); - void setupDistribution(BeamDistributionItem* item) override; - -private slots: - void onMinimumChanged(double value); - void onMaximumChanged(double value); - void onSamplesChanged(int value); - -private: - QDoubleSpinBox* m_minimumSpinBox; - QDoubleSpinBox* m_maximumSpinBox; - QSpinBox* m_samplesSpinBox; - DistributionGateItem* m_item; -}; - -class GaussDistributionForm : public DistributionForm { - Q_OBJECT - -public: - GaussDistributionForm(const std::optional<MeanConfig>& mean_config, QWidget* parent = nullptr, - Qt::WindowFlags f = Qt::WindowFlags()); - void setupDistribution(BeamDistributionItem* item) override; - -private slots: - void onMeanChanged(double value); - void onDeviationChanged(double value); - void onSamplesChanged(int value); - void onSigmaFactorChanged(double value); - -private: - std::variant<QDoubleSpinBox*, ScientificSpinBox*> m_meanSpinBox; - QDoubleSpinBox* m_stdDevSpinBox; - QSpinBox* m_samplesSpinBox; - QDoubleSpinBox* m_sigmaFactorSpinBox; - DistributionGaussianItem* m_item; -}; - - -class LogNormalDistributionForm : public DistributionForm { - Q_OBJECT - -public: - LogNormalDistributionForm(QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags()); - void setupDistribution(BeamDistributionItem* item) override; - -private slots: - void onMedianChanged(double value); - void onScaleChanged(double value); - void onSamplesChanged(int value); - void onSigmaFactorChanged(double value); - -private: - QDoubleSpinBox* m_medianSpinBox; - QDoubleSpinBox* m_scaleSpinBox; - QSpinBox* m_samplesSpinBox; - QDoubleSpinBox* m_sigmaFactorSpinBox; - DistributionLogNormalItem* m_item; -}; - -class LorentzDistributionForm : public DistributionForm { - Q_OBJECT - -public: - LorentzDistributionForm(const std::optional<MeanConfig>& mean_config, QWidget* parent = nullptr, - Qt::WindowFlags f = Qt::WindowFlags()); - void setupDistribution(BeamDistributionItem* item) override; - -private slots: - void onMeanChanged(double value); - void onHWHMChanged(double value); - void onSamplesChanged(int value); - void onSigmaFactorChanged(double value); - -private: - std::variant<QDoubleSpinBox*, ScientificSpinBox*> m_meanSpinBox; - QDoubleSpinBox* m_hwhmSpinBox; - QSpinBox* m_samplesSpinBox; - QDoubleSpinBox* m_sigmaFactorSpinBox; - DistributionLorentzItem* m_item; -}; - -class NoneDistributionForm : public DistributionForm { - Q_OBJECT - -public: - NoneDistributionForm(const std::optional<MeanConfig>& mean_config, QWidget* parent = nullptr, - Qt::WindowFlags f = Qt::WindowFlags()); - void setupDistribution(BeamDistributionItem* item) override; - -private slots: - void onValueChanged(double value); - -private: - std::variant<QDoubleSpinBox*, ScientificSpinBox*> m_spinBox; - DistributionNoneItem* m_item; -}; - -class TrapezoidDistributionForm : public DistributionForm { - Q_OBJECT - -public: - TrapezoidDistributionForm(QWidget* parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags()); - void setupDistribution(BeamDistributionItem* item) override; - -private slots: - void onCenterChanged(double value); - void onLeftWidthChanged(double value); - void onMiddleWidthChanged(double value); - void onRightWidthChanged(double value); - void onSamplesChanged(int value); - -private: - QDoubleSpinBox* m_centerSpinBox; - QDoubleSpinBox* m_leftWidthSpinBox; - QDoubleSpinBox* m_middleWidthSpinBox; - QDoubleSpinBox* m_rightWidthSpinBox; - QSpinBox* m_samplesSpinBox; - DistributionTrapezoidItem* m_item; -}; - -#endif // BORNAGAIN_GUI_VIEW_INSTRUMENT_DISTRIBUTIONFORMS_H diff --git a/GUI/View/Instrument/GISASBeamEditor.cpp b/GUI/View/Instrument/GISASBeamEditor.cpp index 1de5c274a50c8e9d899dc9871ba9f6d711aa7611..1773d43c29ce323fa73e74175a8924a5acc813a9 100644 --- a/GUI/View/Instrument/GISASBeamEditor.cpp +++ b/GUI/View/Instrument/GISASBeamEditor.cpp @@ -41,26 +41,18 @@ GISASBeamEditor::GISASBeamEditor(QWidget* parent, BeamItem* item) intensityEditor->setValidator(validator); form->addRow("Intensity:", intensityEditor); - // valid input range is ]0,inf[ - MeanConfig wave_cfg{boost::numeric::interval<double>(std::numeric_limits<double>::min(), - std::numeric_limits<double>::max()), - 4, true}; auto* wavelengthEditor = new DistributionEditor( - "Wavelength [nm]", wave_cfg, GUI::ID::Distributions::All, this, item->wavelengthItem()); + "Wavelength", MeanConfig{true}, GUI::ID::Distributions::All, this, item->wavelengthItem()); vLayout->addWidget(wavelengthEditor); - // valid input range is [0,90] - MeanConfig incl_cfg{boost::numeric::interval<double>(0.0, 90.0), 3, false}; auto* inclinationEditor = - new DistributionEditor("Inclination angle [deg]", incl_cfg, GUI::ID::Distributions::All, + new DistributionEditor("Inclination angle", MeanConfig{false}, GUI::ID::Distributions::All, this, item->inclinationAngleItem()); vLayout->addWidget(inclinationEditor); - // valid input range is [-90,90] - MeanConfig azim_cfg{boost::numeric::interval<double>(-90.0, 90.0), 3, false}; auto* azimuthalEditor = - new DistributionEditor("Azimuthal angle [deg]", azim_cfg, GUI::ID::Distributions::All, this, - item->azimuthalAngleItem()); + new DistributionEditor("Azimuthal angle", MeanConfig{false}, GUI::ID::Distributions::All, + this, item->azimuthalAngleItem()); vLayout->addWidget(azimuthalEditor); intensityEditor->setText(QString::number(item->intensity())); diff --git a/GUI/View/Instrument/OffSpecularBeamEditor.cpp b/GUI/View/Instrument/OffSpecularBeamEditor.cpp index c8484578fb85e9a6d41bc47939cece73bb8ce5c2..ab23ebc2a3fe56313f595c680cdcf78755b0afb6 100644 --- a/GUI/View/Instrument/OffSpecularBeamEditor.cpp +++ b/GUI/View/Instrument/OffSpecularBeamEditor.cpp @@ -43,23 +43,17 @@ OffSpecularBeamEditor::OffSpecularBeamEditor(QWidget* parent, OffSpecularInstrum intensityEditor->setValidator(validator); form->addRow("Intensity:", intensityEditor); - // valid input range is ]0,inf[ - MeanConfig wave_cfg{boost::numeric::interval<double>(std::numeric_limits<double>::min(), - std::numeric_limits<double>::max()), - 4, true}; auto* wavelengthEditor = - new DistributionEditor("Wavelength [nm]", wave_cfg, GUI::ID::Distributions::All, this, + new DistributionEditor("Wavelength", MeanConfig{true}, GUI::ID::Distributions::All, this, item->beamItem()->wavelengthItem()); vLayout->addWidget(wavelengthEditor); auto* inclinationEditor = new AxisPropertyEditor(this, "Inclination angle", &item->alphaAxis()); vLayout->addWidget(inclinationEditor); - // valid input range is [-90,90] - MeanConfig azim_cfg{boost::numeric::interval<double>(-90.0, 90.0), 3, false}; auto* azimuthalEditor = - new DistributionEditor("Azimuthal angle [deg]", azim_cfg, GUI::ID::Distributions::All, this, - item->beamItem()->azimuthalAngleItem()); + new DistributionEditor("Azimuthal angle", MeanConfig{false}, GUI::ID::Distributions::All, + this, item->beamItem()->azimuthalAngleItem()); vLayout->addWidget(azimuthalEditor); intensityEditor->setText(QString::number(item->beamItem()->intensity())); diff --git a/GUI/View/Instrument/SpecularBeamEditor.cpp b/GUI/View/Instrument/SpecularBeamEditor.cpp index b2f096ee76e6684cee99b71756bb6bdcad07e6ef..c7725d16214c9ba1ed20361a9b34bc2efdc7b1de 100644 --- a/GUI/View/Instrument/SpecularBeamEditor.cpp +++ b/GUI/View/Instrument/SpecularBeamEditor.cpp @@ -45,13 +45,9 @@ SpecularBeamEditor::SpecularBeamEditor(QWidget* parent, SpecularBeamItem* item, intensityLineEdit->setValidator(validator); form->addRow("Intensity:", intensityLineEdit); - // valid input range is ]0,inf[ - MeanConfig wave_cfg{boost::numeric::interval<double>(std::numeric_limits<double>::min(), - std::numeric_limits<double>::max()), - 4, true}; auto* wavelengthEditor = - new DistributionEditor("Wavelength [nm]", wave_cfg, GUI::ID::Distributions::Symmetric, this, - item->wavelengthItem()); + new DistributionEditor("Wavelength", MeanConfig{true}, GUI::ID::Distributions::Symmetric, + this, item->wavelengthItem()); vLayout->addWidget(wavelengthEditor); auto* inclinationEditor = new InclinationAnglesEditor(this, item->inclinationAngleItem());