From 5391c836c939341cd5074626cb1da209cbdfc63f Mon Sep 17 00:00:00 2001
From: Dmitry Yurov <d.yurov@fz-juelich.de>
Date: Thu, 21 Jun 2018 15:56:20 +0200
Subject: [PATCH] Using DiffItemController in FitComparisonController2D

Redmine: #2051
also related changes in FitComparisonWidget
---
 .../FitWidgets/FitComparisonController.cpp    | 83 +++++++++++-------
 .../FitWidgets/FitComparisonController.h      |  9 +-
 .../Views/FitWidgets/FitComparisonWidget.cpp  | 84 ++-----------------
 .../Views/FitWidgets/FitComparisonWidget.h    | 13 ++-
 4 files changed, 69 insertions(+), 120 deletions(-)

diff --git a/GUI/coregui/Views/FitWidgets/FitComparisonController.cpp b/GUI/coregui/Views/FitWidgets/FitComparisonController.cpp
index 69a27809d3e..6d07a7b9228 100644
--- a/GUI/coregui/Views/FitWidgets/FitComparisonController.cpp
+++ b/GUI/coregui/Views/FitWidgets/FitComparisonController.cpp
@@ -23,8 +23,12 @@
 #include "SpecularDataItem.h"
 
 namespace {
-const double default_y_min = 0.0;
-const double default_y_max = 2.0;
+// different limits on relative difference plot are required
+// to provide the best appearance
+const double relative_diff_min_2d = 1e-05;
+const double relative_diff_max_2d = 1.0;
+const double relative_diff_min_1d = 1e-05;
+const double relative_diff_max_1d = 4.0;
 
 template<class DataType>
 DataType* simulationData(JobItem* job_item)
@@ -59,59 +63,74 @@ private:
 
 FitComparisonController2D::FitComparisonController2D(QObject* parent)
     : QObject(parent)
+    , m_diff_item_controller(new DiffItemController(Constants::IntensityDataType, this))
     , m_appearanceRepeater(new PropertyRepeater(this))
     , m_xAxisRepeater(new PropertyRepeater(this))
     , m_yAxisRepeater(new PropertyRepeater(this))
     , m_zAxisRepeater(new PropertyRepeater(this))
-    , m_relativeDiffItem(nullptr)
-    , m_tempIntensityDataModel(new SessionModel("TempIntensityDataModel", this))
 {
-    createRelativeDifferenceItem();
 }
 
 IntensityDataItem* FitComparisonController2D::diffItem()
 {
-    return m_relativeDiffItem;
+    assert(dynamic_cast<IntensityDataItem*>(m_diff_item_controller->diffItem()));
+    return dynamic_cast<IntensityDataItem*>(m_diff_item_controller->diffItem());
 }
 
-void FitComparisonController2D::setItems(IntensityDataItem* realDataItem,
-                                       IntensityDataItem* simDataItem)
+void FitComparisonController2D::setItem(JobItem* job_item)
 {
-    double zmin = realDataItem->getLowerZ();
-    double zmax = realDataItem->getUpperZ();
-    simDataItem->setLowerAndUpperZ(zmin, zmax);
+    assert(job_item);
+
+    clear();
+    m_diff_item_controller->setItem(job_item);
+
+    auto sim_data_item = simulationData<IntensityDataItem>(job_item);
+    auto real_data_item = realData<IntensityDataItem>(job_item);
+
+    double zmin = real_data_item->getLowerZ();
+    double zmax = real_data_item->getUpperZ();
+    sim_data_item->setLowerAndUpperZ(zmin, zmax);
 
-    m_appearanceRepeater->addItem(realDataItem);
-    m_appearanceRepeater->addItem(simDataItem);
+    diffItem()->xAxisItem()->setItemValue(BasicAxisItem::P_TITLE, sim_data_item->getXaxisTitle());
+    diffItem()->yAxisItem()->setItemValue(BasicAxisItem::P_TITLE, sim_data_item->getYaxisTitle());
+    diffItem()->setLowerAndUpperZ(relative_diff_min_2d, relative_diff_max_2d);
+    diffItem()->setAxesRangeToData();
+
+    m_appearanceRepeater->addItem(real_data_item);
+    m_appearanceRepeater->addItem(sim_data_item);
     m_appearanceRepeater->addItem(diffItem());
 
-    m_xAxisRepeater->addItem(realDataItem->xAxisItem());
-    m_xAxisRepeater->addItem(simDataItem->xAxisItem());
+    m_xAxisRepeater->addItem(real_data_item->xAxisItem());
+    m_xAxisRepeater->addItem(sim_data_item->xAxisItem());
     m_xAxisRepeater->addItem(diffItem()->xAxisItem());
 
-    m_yAxisRepeater->addItem(realDataItem->yAxisItem());
-    m_yAxisRepeater->addItem(simDataItem->yAxisItem());
+    m_yAxisRepeater->addItem(real_data_item->yAxisItem());
+    m_yAxisRepeater->addItem(sim_data_item->yAxisItem());
     m_yAxisRepeater->addItem(diffItem()->yAxisItem());
 
-    m_zAxisRepeater->addItem(realDataItem->zAxisItem());
-    m_zAxisRepeater->addItem(simDataItem->zAxisItem());
+    m_zAxisRepeater->addItem(real_data_item->zAxisItem());
+    m_zAxisRepeater->addItem(sim_data_item->zAxisItem());
 }
 
-void FitComparisonController2D::clear()
+void FitComparisonController2D::updateDiffData()
 {
-    m_appearanceRepeater->clear();
+    m_diff_item_controller->updateDiffData();
+}
 
-    m_xAxisRepeater->clear();
-    m_yAxisRepeater->clear();
-    m_zAxisRepeater->clear();
+void FitComparisonController2D::resetDiffItem()
+{
+    diffItem()->resetView();
+    diffItem()->setLowerAndUpperZ(relative_diff_min_2d, relative_diff_max_2d);
 }
 
-void FitComparisonController2D::createRelativeDifferenceItem()
+void FitComparisonController2D::clear()
 {
-    m_tempIntensityDataModel->clear();
+    m_diff_item_controller->unsubscribe();
 
-    m_relativeDiffItem = dynamic_cast<IntensityDataItem*>(
-        m_tempIntensityDataModel->insertNewItem(Constants::IntensityDataType));
+    m_appearanceRepeater->clear();
+    m_xAxisRepeater->clear();
+    m_yAxisRepeater->clear();
+    m_zAxisRepeater->clear();
 }
 
 FitComparisonController1D::FitComparisonController1D(QObject* parent)
@@ -149,8 +168,8 @@ void FitComparisonController1D::setItem(JobItem* job_item)
     diffItem()->setXaxisTitle(sim_data_item->getXaxisTitle());
     diffItem()->setYaxisTitle("Relative difference");
     diffItem()->setLog(false);
-    diffItem()->setLowerY(default_y_min);
-    diffItem()->setUpperY(default_y_max);
+    diffItem()->setLowerY(relative_diff_min_1d);
+    diffItem()->setUpperY(relative_diff_max_1d);
 }
 
 void FitComparisonController1D::updateDiffData()
@@ -161,8 +180,8 @@ void FitComparisonController1D::updateDiffData()
 void FitComparisonController1D::resetDiffItem()
 {
     diffItem()->resetView();
-    diffItem()->setLowerY(default_y_min);
-    diffItem()->setUpperY(default_y_max);
+    diffItem()->setLowerY(relative_diff_min_1d);
+    diffItem()->setUpperY(relative_diff_max_1d);
 }
 
 void FitComparisonController1D::clear()
diff --git a/GUI/coregui/Views/FitWidgets/FitComparisonController.h b/GUI/coregui/Views/FitWidgets/FitComparisonController.h
index 4b4295c4579..fb087be7335 100644
--- a/GUI/coregui/Views/FitWidgets/FitComparisonController.h
+++ b/GUI/coregui/Views/FitWidgets/FitComparisonController.h
@@ -36,19 +36,18 @@ public:
 
     IntensityDataItem* diffItem();
 
-    void setItems(IntensityDataItem* realDataItem, IntensityDataItem* simDataItem);
+    void setItem(JobItem* job_item);
+    void updateDiffData();
+    void resetDiffItem();
 
     void clear();
 
 private:
-    void createRelativeDifferenceItem();
-
+    DiffItemController* m_diff_item_controller;
     PropertyRepeater* m_appearanceRepeater;
     PropertyRepeater* m_xAxisRepeater;
     PropertyRepeater* m_yAxisRepeater;
     PropertyRepeater* m_zAxisRepeater;
-    IntensityDataItem* m_relativeDiffItem;
-    SessionModel* m_tempIntensityDataModel;
 };
 
 //! Provides synchronization between certain properties of fit related SpecularDataItems.
diff --git a/GUI/coregui/Views/FitWidgets/FitComparisonWidget.cpp b/GUI/coregui/Views/FitWidgets/FitComparisonWidget.cpp
index 3a4fe527044..fa5aebf2b32 100644
--- a/GUI/coregui/Views/FitWidgets/FitComparisonWidget.cpp
+++ b/GUI/coregui/Views/FitWidgets/FitComparisonWidget.cpp
@@ -13,33 +13,19 @@
 // ************************************************************************** //
 
 #include "FitComparisonWidget.h"
-#include "AxesItems.h"
 #include "ColorMap.h"
 #include "ColorMapCanvas.h"
-#include "PlotStatusLabel.h"
+#include "FitComparisonController.h"
 #include "FitFlowWidget.h"
-#include "IntensityDataFunctions.h"
+#include "FitSuiteItem.h"
 #include "IntensityDataItem.h"
+#include "IntensityDataPropertyWidget.h"
 #include "JobItem.h"
+#include "PlotStatusLabel.h"
 #include "RealDataItem.h"
-#include "SessionModel.h"
-#include "FitSuiteItem.h"
-#include "PropertyRepeater.h"
-#include "IntensityDataPropertyWidget.h"
-#include "AxesItems.h"
-#include "FitComparisonController.h"
-#include "JobItemUtils.h"
 #include <QAction>
 #include <QGridLayout>
-#include <QLabel>
-#include <QVBoxLayout>
 #include <QVBoxLayout>
-#include <QDebug>
-
-namespace {
-const double relative_diff_min = 1e-05;
-const double relative_diff_max = 1;
-}
 
 FitComparisonWidget::FitComparisonWidget(QWidget *parent)
     : SessionItemWidget(parent)
@@ -47,7 +33,7 @@ FitComparisonWidget::FitComparisonWidget(QWidget *parent)
     , m_simulatedDataPlot(new ColorMapCanvas)
     , m_relativeDiffPlot(new ColorMapCanvas)
     , m_fitFlowWidget(new FitFlowWidget)
-    , m_statusLabel(new PlotStatusLabel(0, this))
+    , m_statusLabel(new PlotStatusLabel(nullptr, this))
     , m_propertyWidget(new IntensityDataPropertyWidget)
     , m_resetViewAction(new QAction(this))
     , m_comparisonController(new FitComparisonController2D(this))
@@ -80,15 +66,10 @@ FitComparisonWidget::FitComparisonWidget(QWidget *parent)
     m_resetViewAction->setToolTip("Reset View");
     connect(m_resetViewAction, &QAction::triggered, this, &FitComparisonWidget::onResetViewAction);
 
-    m_relativeDiffPlot->setItem(m_comparisonController->diffItem());
     m_propertyWidget->setVisible(false);
 }
 
-FitComparisonWidget::~FitComparisonWidget()
-{
-    unsubscribeFromChildren();
-}
-
+FitComparisonWidget::~FitComparisonWidget() = default;
 
 QList<QAction*> FitComparisonWidget::actionList()
 {
@@ -109,13 +90,10 @@ void FitComparisonWidget::subscribeToItem()
         },
         this);
 
-    if (auto simItem = simulatedDataItem()) {
-        simItem->mapper()->setOnValueChange([this]() { calculateRelativeDifference(); }, this);
-    }
-    calculateRelativeDifference();
-
+    m_comparisonController->setItem(jobItem());
     m_realDataPlot->setItem(realDataItem());
     m_simulatedDataPlot->setItem(simulatedDataItem());
+    m_relativeDiffPlot->setItem(m_comparisonController->diffItem());
     m_fitFlowWidget->setItem(jobItem()->fitSuiteItem());
 
     m_statusLabel->reset();
@@ -123,26 +101,11 @@ void FitComparisonWidget::subscribeToItem()
     m_statusLabel->addPlot(m_simulatedDataPlot->colorMap());
     m_statusLabel->addPlot(m_relativeDiffPlot->colorMap());
 
-    m_comparisonController->setItems(realDataItem(), simulatedDataItem());
-
-    if (auto diff_item = diffItem())
-        diff_item->mapper()->setOnPropertyChange(
-            [this, diff_item](const QString& name) {
-                if (name == DataItem::P_AXES_UNITS)
-                    diff_item->updateAxesUnits(jobItem()->instrumentItem());
-            },
-            this);
-
     m_propertyWidget->setItem(simulatedDataItem());
 }
 
 void FitComparisonWidget::unsubscribeFromItem()
 {
-    if (!currentItem())
-        return;
-
-    unsubscribeFromChildren();
-
     m_comparisonController->clear();
 }
 
@@ -151,36 +114,7 @@ void FitComparisonWidget::onResetViewAction()
     if (auto item = realDataItem())
         item->resetView();
 
-    if (diffItem()) {
-        diffItem()->setLowerAndUpperZ(relative_diff_min, relative_diff_max);
-    }
-}
-
-void FitComparisonWidget::calculateRelativeDifference()
-{
-    if (!simulatedDataItem()->getOutputData()) // job failed
-        return;
-
-    Q_ASSERT(realDataItem());
-    Q_ASSERT(simulatedDataItem());
-    Q_ASSERT(diffItem());
-
-    diffItem()->setOutputData(IntensityDataFunctions::createRelativeDifferenceData(
-        *simulatedDataItem()->getOutputData(), *realDataItem()->getOutputData()).release());
-
-    diffItem()->xAxisItem()->setItemValue(BasicAxisItem::P_TITLE, simulatedDataItem()->getXaxisTitle());
-    diffItem()->yAxisItem()->setItemValue(BasicAxisItem::P_TITLE, simulatedDataItem()->getYaxisTitle());
-    diffItem()->setLowerAndUpperZ(relative_diff_min, relative_diff_max);
-    diffItem()->setAxesRangeToData();
-}
-
-void FitComparisonWidget::unsubscribeFromChildren()
-{
-    if (jobItem() && simulatedDataItem())
-        simulatedDataItem()->mapper()->unsubscribe(this);
-
-    if (diffItem())
-        diffItem()->mapper()->unsubscribe(this);
+    m_comparisonController->resetDiffItem();
 }
 
 JobItem* FitComparisonWidget::jobItem()
diff --git a/GUI/coregui/Views/FitWidgets/FitComparisonWidget.h b/GUI/coregui/Views/FitWidgets/FitComparisonWidget.h
index f51b11d77af..150e278ac67 100644
--- a/GUI/coregui/Views/FitWidgets/FitComparisonWidget.h
+++ b/GUI/coregui/Views/FitWidgets/FitComparisonWidget.h
@@ -37,22 +37,19 @@ class BA_CORE_API_ FitComparisonWidget : public SessionItemWidget
     Q_OBJECT
 
 public:
-    explicit FitComparisonWidget(QWidget* parent = 0);
-    ~FitComparisonWidget();
+    explicit FitComparisonWidget(QWidget* parent = nullptr);
+    ~FitComparisonWidget() override;
 
-    virtual QList<QAction*> actionList();
+    virtual QList<QAction*> actionList() override;
 
 private slots:
     void onResetViewAction();
 
 protected:
-    void subscribeToItem();
-    void unsubscribeFromItem();
+    void subscribeToItem() override;
+    void unsubscribeFromItem() override;
 
 private:
-    void calculateRelativeDifference();
-    void unsubscribeFromChildren();
-
     JobItem* jobItem();
     IntensityDataItem* realDataItem();
     IntensityDataItem* simulatedDataItem();
-- 
GitLab