diff --git a/Examples/python/fitting/ex02_FitCylindersAndPrisms/FitCylindersPrisms_detailed.py b/Examples/python/fitting/ex02_FitCylindersAndPrisms/FitCylindersPrisms_detailed.py index 65991e98c2f7a41bea87a833fa164058e7d26f70..5252f77fe7a8bac6e4b774fb38d1286a4783b66e 100644 --- a/Examples/python/fitting/ex02_FitCylindersAndPrisms/FitCylindersPrisms_detailed.py +++ b/Examples/python/fitting/ex02_FitCylindersAndPrisms/FitCylindersPrisms_detailed.py @@ -154,7 +154,7 @@ def run_fitting(): fit_suite.addFitParameter("*Cylinder/Height", 4.*nanometer, AttLimits.lowerLimited(0.01)) fit_suite.addFitParameter("*Cylinder/Radius", 6.*nanometer, AttLimits.lowerLimited(0.01)) fit_suite.addFitParameter("*Prism3/Height", 4.*nanometer, AttLimits.lowerLimited(0.01)) - fit_suite.addFitParameter("*Prism3/Length", 12.*nanometer, AttLimits.lowerLimited(0.01)) + fit_suite.addFitParameter("*Prism3/BaseEdge", 12.*nanometer, AttLimits.lowerLimited(0.01)) # running fit fit_suite.runFit() diff --git a/GUI/coregui/Models/FitParameterModel.cpp b/GUI/coregui/Models/FitParameterModel.cpp index 92f07385475bd333c5573f421b52b0823bf9657a..7f128f51df28704021d07175b43855ecd01eb349 100644 --- a/GUI/coregui/Models/FitParameterModel.cpp +++ b/GUI/coregui/Models/FitParameterModel.cpp @@ -35,6 +35,7 @@ FitParameterModel::FitParameterModel(SessionItem *fitParContainer, QObject *pare FitParameterModel::~FitParameterModel() { setRootItem(0); + qDebug() << "FitParameterModel::~FitParameterModel()"; } Qt::ItemFlags FitParameterModel::flags(const QModelIndex &index) const diff --git a/GUI/coregui/Models/FitSuiteItem.cpp b/GUI/coregui/Models/FitSuiteItem.cpp index 3417f25e3a5fcef8bb46e830611b77389163ae56..56ccde8c2926118c57f1cad5199c542b6f7a82cd 100644 --- a/GUI/coregui/Models/FitSuiteItem.cpp +++ b/GUI/coregui/Models/FitSuiteItem.cpp @@ -16,15 +16,29 @@ #include "FitSuiteItem.h" #include "FitSuite.h" +#include "FitParameterItems.h" +const QString FitSuiteItem::P_UPDATE_INTERVAL = "Update interval"; +const QString FitSuiteItem::P_ITERATION_COUNT = "Number of iterations"; +const QString FitSuiteItem::P_CHI2 = "Chi2"; const QString FitSuiteItem::T_FIT_PARAMETERS = "Fit parameters container"; + FitSuiteItem::FitSuiteItem() : SessionItem(Constants::FitSuiteType) { + addProperty(P_UPDATE_INTERVAL, 10); + addProperty(P_ITERATION_COUNT, 0); + addProperty(P_CHI2, 0.0); + registerTag(T_FIT_PARAMETERS, 1, 1, QStringList() << Constants::FitParameterContainerType); } +FitParameterContainerItem *FitSuiteItem::fitParameterContainerItem() +{ + return dynamic_cast<FitParameterContainerItem *>(getItem(FitSuiteItem::T_FIT_PARAMETERS)); +} + //std::unique_ptr<FitSuite> FitSuiteItem::createFitSuite() //{ // std::unique_ptr<FitSuite> result(new FitSuite); diff --git a/GUI/coregui/Models/FitSuiteItem.h b/GUI/coregui/Models/FitSuiteItem.h index 2de67776510f0e676c6425f74c8b23af2e1c8ea8..ceeae99cc5bb2867eeb55b269a34bbfbd13a2691 100644 --- a/GUI/coregui/Models/FitSuiteItem.h +++ b/GUI/coregui/Models/FitSuiteItem.h @@ -20,14 +20,19 @@ #include "SessionItem.h" class FitSuite; +class FitParameterContainerItem; class BA_CORE_API_ FitSuiteItem : public SessionItem { public: + static const QString P_UPDATE_INTERVAL; + static const QString P_ITERATION_COUNT; + static const QString P_CHI2; static const QString T_FIT_PARAMETERS; explicit FitSuiteItem(); + FitParameterContainerItem *fitParameterContainerItem(); // std::unique_ptr<FitSuite> createFitSuite(); }; diff --git a/GUI/coregui/Models/JobItem.cpp b/GUI/coregui/Models/JobItem.cpp index 8af9a424101f02e01382c95a0622d206f7081806..bfc2dfbf988465c8e4aa9b778c740bdb310f7c83 100644 --- a/GUI/coregui/Models/JobItem.cpp +++ b/GUI/coregui/Models/JobItem.cpp @@ -24,6 +24,9 @@ #include "JobResultsPresenter.h" #include "SimulationOptionsItem.h" #include "GUIHelpers.h" +#include "FitSuiteItem.h" +#include "ParameterTreeItems.h" +#include "FitParameterItems.h" #include <QDateTime> #include <QDebug> @@ -243,6 +246,24 @@ void JobItem::setResults(const GISASSimulation *simulation) JobResultsPresenter::setResults(intensityItem, simulation); } +FitSuiteItem *JobItem::fitSuiteItem() +{ + return dynamic_cast<FitSuiteItem *>(getItem(JobItem::T_FIT_SUITE)); +} + +ParameterContainerItem *JobItem::parameterContainerItem() +{ + return dynamic_cast<ParameterContainerItem *>(getItem(JobItem::T_PARAMETER_TREE)); +} + +FitParameterContainerItem *JobItem::fitParameterContainerItem() +{ + if(FitSuiteItem *item = fitSuiteItem()) + return item->fitParameterContainerItem(); + + return nullptr; +} + SimulationOptionsItem *JobItem::getSimulationOptionsItem() { return const_cast<SimulationOptionsItem *>(static_cast<const JobItem*>(this)->getSimulationOptionsItem()); diff --git a/GUI/coregui/Models/JobItem.h b/GUI/coregui/Models/JobItem.h index 3ba483b3ad20bd06023769336650e91d970382f9..5dfbdbfaa0f33cc4468cbbf56a6ca3a284c2d752 100644 --- a/GUI/coregui/Models/JobItem.h +++ b/GUI/coregui/Models/JobItem.h @@ -25,6 +25,9 @@ class GISASSimulation; class MultiLayerItem; class InstrumentItem; class SimulationOptionsItem; +class FitSuiteItem; +class ParameterContainerItem; +class FitParameterContainerItem; class BA_CORE_API_ JobItem : public SessionItem { @@ -91,6 +94,10 @@ public: void setResults(const GISASSimulation *simulation); + FitSuiteItem *fitSuiteItem(); + ParameterContainerItem *parameterContainerItem(); + FitParameterContainerItem *fitParameterContainerItem(); + private: const SimulationOptionsItem *getSimulationOptionsItem() const; }; diff --git a/GUI/coregui/Views/FitWidgets/FitActivityPanel.cpp b/GUI/coregui/Views/FitWidgets/FitActivityPanel.cpp index 7d730e9dca4cbfea6d841124ff1b2bc61929e2c5..b707a99d6bc0590f1cbacf23c8fef2d64e810eda 100644 --- a/GUI/coregui/Views/FitWidgets/FitActivityPanel.cpp +++ b/GUI/coregui/Views/FitWidgets/FitActivityPanel.cpp @@ -65,6 +65,8 @@ void FitActivityPanel::setItem(JobItem *item) { if(!item) return; + m_controlWidget->setItem(item); + m_currentItem = item; if(!isVisible()) return; diff --git a/GUI/coregui/Views/FitWidgets/FitParametersWidget.cpp b/GUI/coregui/Views/FitWidgets/FitParametersWidget.cpp index 8e4fc6b946350b571cc30e9d9ee4f605d2d23867..cbca886872e83230942f0111a60c888e837adae5 100644 --- a/GUI/coregui/Views/FitWidgets/FitParametersWidget.cpp +++ b/GUI/coregui/Views/FitWidgets/FitParametersWidget.cpp @@ -47,6 +47,7 @@ FitParametersWidget::FitParametersWidget(QWidget *parent) FitParametersWidget::~FitParametersWidget() { + qDebug() << "FitParametersWidget::~FitParametersWidget()"; } diff --git a/GUI/coregui/Views/FitWidgets/FitSuiteWidget.cpp b/GUI/coregui/Views/FitWidgets/FitSuiteWidget.cpp index bffb79cf4f1e13921b2fb5f13a8d0154ac359952..a741845d0914c39624598d73ca4d8a0d97d24b7b 100644 --- a/GUI/coregui/Views/FitWidgets/FitSuiteWidget.cpp +++ b/GUI/coregui/Views/FitWidgets/FitSuiteWidget.cpp @@ -78,10 +78,12 @@ void FitSuiteWidget::onUpdatePlots(OutputData<double> *sim, OutputData<double> * { Q_UNUSED(sim); Q_UNUSED(chi2); + // FIXME Ownership sim,chi2 - shouldn't they be deleted here? + qDebug() << "FitSuiteWidget::onUpdatePlots"; - OutputData<double> *data = m_currentItem->getIntensityDataItem()->getOutputData(); - data->setRawDataVector(sim->getRawDataVector()); - m_currentItem->getIntensityDataItem()->emitDataChanged(); +// OutputData<double> *data = m_currentItem->getIntensityDataItem()->getOutputData(); +// data->setRawDataVector(sim->getRawDataVector()); +// m_currentItem->getIntensityDataItem()->emitDataChanged(); m_observer->finishedPlotting(); } @@ -89,16 +91,13 @@ void FitSuiteWidget::onUpdateParameters(const QStringList ¶meters, QVector<d { qDebug() << "FitSuiteWidget::onUpdateParameters" << parameters << values; - ParameterContainerItem *parContainer = dynamic_cast<ParameterContainerItem *>(m_currentItem->getItem(JobItem::T_PARAMETER_TREE)); + ParameterContainerItem *parContainer = m_currentItem->parameterContainerItem(); Q_ASSERT(parContainer); - SessionItem *fitSuiteItem = m_currentItem->getItem(JobItem::T_FIT_SUITE); - Q_ASSERT(fitSuiteItem); - - SessionItem *container = fitSuiteItem->getItem(FitSuiteItem::T_FIT_PARAMETERS); - Q_ASSERT(container); + SessionItem *fitParContainer = m_currentItem->fitParameterContainerItem(); + Q_ASSERT(fitParContainer); - foreach(SessionItem *fitParItem, container->getItems(FitParameterContainerItem::T_FIT_PARAMETERS)) { + foreach(SessionItem *fitParItem, fitParContainer->getItems(FitParameterContainerItem::T_FIT_PARAMETERS)) { foreach(SessionItem *linkItem, fitParItem->getItems(FitParameterItem::T_LINK)) { QString domainPath = linkItem->getItemValue(FitParameterLinkItem::P_DOMAIN).toString(); @@ -115,6 +114,17 @@ void FitSuiteWidget::onUpdateParameters(const QStringList ¶meters, QVector<d } +void FitSuiteWidget::onUpdateStatus(const QString &text) +{ + Q_ASSERT(m_currentItem); + qDebug() << "FitSuiteWidget::onUpdateStatus(const QString &text)" << text; + FitSuiteItem *fitSuiteItem = m_currentItem->fitSuiteItem(); + Q_ASSERT(fitSuiteItem); + bool ok; + int niter = text.toInt(&ok); + fitSuiteItem->setItemValue(FitSuiteItem::P_ITERATION_COUNT, niter); +} + void FitSuiteWidget::startFitting() { if(!m_currentItem) @@ -158,5 +168,7 @@ void FitSuiteWidget::connectSignals() this, SLOT(onUpdatePlots(OutputData<double>*,OutputData<double>*))); connect(m_observer.get(), SIGNAL(updateParameters(QStringList,QVector<double>)), this, SLOT(onUpdateParameters(QStringList,QVector<double>))); + connect(m_observer.get(), SIGNAL(updateStatus(QString)), + this, SLOT(onUpdateStatus(QString))); } diff --git a/GUI/coregui/Views/FitWidgets/FitSuiteWidget.h b/GUI/coregui/Views/FitWidgets/FitSuiteWidget.h index 350b364a4cfe1ae2faed83de5d4bfea01625dd60..ed54eb839c49ad179c644241a9da5744b9472d17 100644 --- a/GUI/coregui/Views/FitWidgets/FitSuiteWidget.h +++ b/GUI/coregui/Views/FitWidgets/FitSuiteWidget.h @@ -32,7 +32,8 @@ template <class T> class OutputData; //! The FitSuiteWidget contains all fit settings for given JobItem (fit parameters, -//! minimizer settings) and all logic to start/stop fitting. Controlled by FitActivityPanel +//! minimizer settings) and all logic to communicate with fit observers. +//! Controlled by FitActivityPanel. class BA_CORE_API_ FitSuiteWidget : public QWidget { @@ -54,6 +55,7 @@ public slots: void onError(const QString &text); void onUpdatePlots(OutputData<double>*sim, OutputData<double>*chi2); void onUpdateParameters(const QStringList ¶meters, QVector<double> values); + void onUpdateStatus(const QString &text); void startFitting(); void stopFitting(); diff --git a/GUI/coregui/Views/FitWidgets/GUIFitObserver.cpp b/GUI/coregui/Views/FitWidgets/GUIFitObserver.cpp index 29b7f233bf07611b2561729707a007772b355b22..1605914b779fa694ff91e25cff63a18d25fff7ac 100644 --- a/GUI/coregui/Views/FitWidgets/GUIFitObserver.cpp +++ b/GUI/coregui/Views/FitWidgets/GUIFitObserver.cpp @@ -71,7 +71,8 @@ void GUIFitObserver::update(FitSuite *subject) if (curIteration % m_update_interval == 0 && !m_block_update_plots) { m_block_update_plots = true; - emit updateStatus(QString("Iteration: %1").arg(subject->getNumberOfIterations())); +// emit updateStatus(QString("Iteration: %1").arg(subject->getNumberOfIterations())); + emit updateStatus(QString::number(subject->getNumberOfIterations())); emit updatePlots(subject->getSimulationOutputData()->clone(), subject->getChiSquaredOutputData()->clone()); diff --git a/GUI/coregui/Views/FitWidgets/RunFitControlWidget.cpp b/GUI/coregui/Views/FitWidgets/RunFitControlWidget.cpp index e89d163dfec58a0b26c356132b327679b3db203a..af0fc4307f394bd2e42fe72f34e60a93feaa09a9 100644 --- a/GUI/coregui/Views/FitWidgets/RunFitControlWidget.cpp +++ b/GUI/coregui/Views/FitWidgets/RunFitControlWidget.cpp @@ -17,6 +17,8 @@ #include "RunFitControlWidget.h" #include "WarningSignWidget.h" #include "DesignerHelper.h" +#include "JobItem.h" +#include "FitSuiteItem.h" #include <QPushButton> #include <QSlider> #include <QLabel> @@ -38,6 +40,7 @@ RunFitControlWidget::RunFitControlWidget(QWidget *parent) , m_stopButton(new QPushButton) , m_intervalSlider(new QSlider) , m_updateIntervalLabel(new QLabel("25")) + , m_iterationsCountLabel(new QLabel()) , m_currentItem(0) , m_warningSign(0) { @@ -77,6 +80,7 @@ RunFitControlWidget::RunFitControlWidget(QWidget *parent) layout->addWidget(m_updateIntervalLabel); layout->addSpacing(5); layout->addStretch(); + layout->addWidget(m_iterationsCountLabel); setLayout(layout); connect(m_startButton, SIGNAL(clicked(bool)), this, SIGNAL(startFitting())); @@ -90,12 +94,20 @@ void RunFitControlWidget::onFittingStarted() clearWarningSign(); m_startButton->setEnabled(false); m_stopButton->setEnabled(true); + + fitSuiteItem()->mapper()->setOnPropertyChange( + [this](const QString &name) + { + onFitSuitePropertyChange(name); + }, this); + } void RunFitControlWidget::onFittingFinished() { m_startButton->setEnabled(true); m_stopButton->setEnabled(false); + fitSuiteItem()->mapper()->unsubscribe(this); } void RunFitControlWidget::onFittingError(const QString &what) @@ -124,6 +136,16 @@ void RunFitControlWidget::onSliderValueChanged(int value) m_updateIntervalLabel->setText(QString::number(sliderValueToUpdateInterval(value))); } +void RunFitControlWidget::onFitSuitePropertyChange(const QString &name) +{ + if(name == FitSuiteItem::P_ITERATION_COUNT) { + int niter = fitSuiteItem()->getItemValue(FitSuiteItem::P_ITERATION_COUNT).toInt(); + qDebug() << "QQQ" << name << niter; + m_iterationsCountLabel->setText(QString::number(niter)); + } + +} + void RunFitControlWidget::resizeEvent(QResizeEvent *event) { Q_UNUSED(event); @@ -154,3 +176,11 @@ int RunFitControlWidget::sliderValueToUpdateInterval(int value) return default_update_interval; } + +FitSuiteItem *RunFitControlWidget::fitSuiteItem() +{ + Q_ASSERT(m_currentItem); + FitSuiteItem *result = m_currentItem->fitSuiteItem(); + Q_ASSERT(result); + return result; +} diff --git a/GUI/coregui/Views/FitWidgets/RunFitControlWidget.h b/GUI/coregui/Views/FitWidgets/RunFitControlWidget.h index 91226f072e0ee173985a81ea7d073111b11ca3d1..396553020669c5b878891c7c6ba105769ad293e5 100644 --- a/GUI/coregui/Views/FitWidgets/RunFitControlWidget.h +++ b/GUI/coregui/Views/FitWidgets/RunFitControlWidget.h @@ -25,6 +25,7 @@ class QPushButton; class QSlider; class WarningSignWidget; class QLabel; +class FitSuiteItem; //! The RunFitControlWidget contains elements to start/stop fitting and to provide minimal //! diagnostic. Part of FitActivityPanel. @@ -47,6 +48,7 @@ public slots: private slots: void onSliderValueChanged(int value); + void onFitSuitePropertyChange(const QString &name); protected: void resizeEvent(QResizeEvent *event); @@ -55,11 +57,13 @@ private: QPoint getPositionForWarningSign(); void clearWarningSign(); int sliderValueToUpdateInterval(int value); + FitSuiteItem *fitSuiteItem(); QPushButton *m_startButton; QPushButton *m_stopButton; QSlider *m_intervalSlider; QLabel *m_updateIntervalLabel; + QLabel *m_iterationsCountLabel; JobItem *m_currentItem; WarningSignWidget *m_warningSign; };