From fb96af0153d895beab5489269f657ae11e1115e7 Mon Sep 17 00:00:00 2001
From: Olivier Langella <olivier.langella@u-psud.fr>
Date: Tue, 19 Dec 2017 09:57:53 +0100
Subject: [PATCH] introducing custom plot in xtpcpp

---
 src/CMakeLists.txt                     |  8 ++--
 src/gui/project_view/project_view.ui   | 55 +++++++++++++++-----------
 src/gui/project_view/projectwindow.cpp | 25 ++++++++++++
 src/utils/utils.cpp                    | 41 ++++++++++++-------
 src/utils/utils.h                      |  2 +-
 5 files changed, 90 insertions(+), 41 deletions(-)

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 0410712ba..d576d6d8c 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -13,10 +13,10 @@ SET(xtpcpp_RCCS xtpcpp.qrc)
 #FIND_PACKAGE(Boost REQUIRED)
 #INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIRS})
 
-FIND_PACKAGE( Qt5 COMPONENTS Core Gui Svg Xml REQUIRED )
+FIND_PACKAGE( Qt5 COMPONENTS Core Gui Svg Xml PrintSupport REQUIRED )
 QT5_ADD_RESOURCES(xtpcpp_RCC_SRCS ${xtpcpp_RCCS})
 
-
+FIND_PACKAGE( QCustomPlot REQUIRED )
 FIND_PACKAGE( Odsstream REQUIRED ) #ODSSTREAM_INCLUDE_DIR AND ODSSTREAM_LIBRARY
 #SET (ODSSTREAM_DIR  "/home/olivier/eclipse/git/cpp_libodsstream")
 #SET (ODSSTREAM_INCLUDE_DIR "${ODSSTREAM_DIR}/src")
@@ -232,8 +232,8 @@ target_compile_definitions(xtpcpp PUBLIC ${QT_DEFINITIONS})
     #COMPILE_DEFINITIONS "${QT_DEFINITIONS}"
     #INCLUDE_DIRECTORIES "${QT_INCLUDE_DIR} ${QT_QTCORE_INCLUDE_DIR}"
     )
-TARGET_LINK_LIBRARIES(xtpcpp ${PAPPSOMSPP_QT5_LIBRARY} ${Pwiz_LIBRARY} ${ODSSTREAM_QT5_LIBRARY} 
-Qt5::Gui Qt5::Xml Qt5::Svg)
+TARGET_LINK_LIBRARIES(xtpcpp ${PAPPSOMSPP_QT5_LIBRARY} ${Pwiz_LIBRARY} ${ODSSTREAM_QT5_LIBRARY} ${QCustomPlot_LIBRARIES}
+Qt5::Gui Qt5::Xml Qt5::Svg Qt5::PrintSupport)
 
 INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/xtpcpp DESTINATION bin)
 
diff --git a/src/gui/project_view/project_view.ui b/src/gui/project_view/project_view.ui
index 72e0934a4..92edffd52 100644
--- a/src/gui/project_view/project_view.ui
+++ b/src/gui/project_view/project_view.ui
@@ -24,7 +24,7 @@
        <string/>
       </property>
       <property name="currentIndex">
-       <number>2</number>
+       <number>0</number>
       </property>
       <widget class="QWidget" name="identifications">
        <attribute name="title">
@@ -274,27 +274,6 @@
             <item row="0" column="0">
              <layout class="QFormLayout" name="formLayout_3"/>
             </item>
-            <item row="1" column="0">
-             <widget class="QLabel" name="label_2">
-              <property name="text">
-               <string>mean</string>
-              </property>
-             </widget>
-            </item>
-            <item row="2" column="0">
-             <widget class="QLabel" name="label_4">
-              <property name="text">
-               <string>median</string>
-              </property>
-             </widget>
-            </item>
-            <item row="3" column="0">
-             <widget class="QLabel" name="label_5">
-              <property name="text">
-               <string>standard deviation</string>
-              </property>
-             </widget>
-            </item>
             <item row="0" column="1">
              <widget class="QComboBox" name="precision_unit_combobox">
               <item>
@@ -309,6 +288,13 @@
               </item>
              </widget>
             </item>
+            <item row="1" column="0">
+             <widget class="QLabel" name="label_2">
+              <property name="text">
+               <string>mean</string>
+              </property>
+             </widget>
+            </item>
             <item row="1" column="1">
              <widget class="QLabel" name="mass_precision_mean_label">
               <property name="text">
@@ -316,6 +302,13 @@
               </property>
              </widget>
             </item>
+            <item row="2" column="0">
+             <widget class="QLabel" name="label_4">
+              <property name="text">
+               <string>median</string>
+              </property>
+             </widget>
+            </item>
             <item row="2" column="1">
              <widget class="QLabel" name="mass_precision_median_label">
               <property name="text">
@@ -323,6 +316,13 @@
               </property>
              </widget>
             </item>
+            <item row="3" column="0">
+             <widget class="QLabel" name="label_5">
+              <property name="text">
+               <string>standard deviation</string>
+              </property>
+             </widget>
+            </item>
             <item row="3" column="1">
              <widget class="QLabel" name="mass_precision_sd_label">
               <property name="toolTip">
@@ -335,6 +335,9 @@
             </item>
            </layout>
           </item>
+          <item>
+           <widget class="QCustomPlot" name="mass_histogram_widget" native="true"/>
+          </item>
          </layout>
         </item>
        </layout>
@@ -355,6 +358,14 @@
   </widget>
   <widget class="QStatusBar" name="statusbar"/>
  </widget>
+ <customwidgets>
+  <customwidget>
+   <class>QCustomPlot</class>
+   <extends>QWidget</extends>
+   <header>qcustomplot.h</header>
+   <container>1</container>
+  </customwidget>
+ </customwidgets>
  <resources/>
  <connections>
   <connection>
diff --git a/src/gui/project_view/projectwindow.cpp b/src/gui/project_view/projectwindow.cpp
index bcbfed308..76dd32d65 100644
--- a/src/gui/project_view/projectwindow.cpp
+++ b/src/gui/project_view/projectwindow.cpp
@@ -35,6 +35,8 @@
 #include <numeric>
 #include "../workerthread.h"
 #include "../../core/labeling/labelingmethod.h"
+#include "../../../utils/utils.h"
+#include <qcustomplot.h>
 
 
 
@@ -281,6 +283,29 @@ void ProjectWindow::computeMassPrecision() {
         ui->mass_precision_mean_label->setText(QString::number(mean,'f',10));
         ui->mass_precision_median_label->setText(QString::number(median,'f',10));
         ui->mass_precision_sd_label->setText(QString::number(sd,'f',10));
+
+
+        std::vector< std::pair<pappso::pappso_double, size_t >> histogram = Utils::getHistogram(delta_list, 100);
+        // generate some data:
+        QVector<double> x, y;
+        for (std::pair<pappso::pappso_double, size_t > & mass_pair: histogram)
+        {
+            x.push_back(mass_pair.first);
+            y.push_back(mass_pair.second);
+        }
+
+        QCPGraph * p_graph = ui->mass_histogram_widget->addGraph();
+        //p_graph->setName("raw xic");
+        //QPen pen;
+        //pen.setColor(getNewColors());
+        //graph()->setPen(pen);
+        //graph()->setName(lineNames.at(i-QCPGraph::lsNone));
+        p_graph->setLineStyle(QCPGraph::LineStyle::lsStepCenter);
+        //p_graph->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssDisc, 2.0));
+        p_graph->setData(x,y);
+        p_graph->rescaleAxes(true);
+        ui->mass_histogram_widget->rescaleAxes();
+        ui->mass_histogram_widget->replot();
     }
     catch (pappso::PappsoException exception_pappso) {
         ui->mass_precision_mean_label->setText("0");
diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp
index 52a4a8025..32aaeb9df 100644
--- a/src/utils/utils.cpp
+++ b/src/utils/utils.cpp
@@ -1,6 +1,7 @@
 #include "utils.h"
 #include <pappsomspp/exception/exceptionnotfound.h>
 #include <pappsomspp/mass_range.h>
+#include <cmath>
 
 const QUrl Utils::getOlsUrl(QString psimod_accession) {
 
@@ -9,7 +10,7 @@ const QUrl Utils::getOlsUrl(QString psimod_accession) {
     return url;
 }
 
-const QString Utils::getXmlDouble(pappso::pappso_double number){
+const QString Utils::getXmlDouble(pappso::pappso_double number) {
     return QString::number(number,'g',6);
 }
 
@@ -37,20 +38,32 @@ const QString Utils::getDatabaseName(ExternalDatabase database) {
 }
 
 
-std::vector<size_t> Utils::getHistogram(std::vector<pappso::pappso_double> data_values, unsigned int number_of_class) {
-
-
-    std::vector<size_t> histogram(number_of_class);
-    
-    std::sort(data_values.begin(), data_values.end());
-    pappso::pappso_double min = *data_values.begin();
-    pappso::pappso_double max = *(data_values.end()-1);
-    pappso::pappso_double offset = (max-min)/ (pappso::pappso_double) number_of_class;
-
-    for (pappso::pappso_double value :data_values) {
-        histogram[(value /offset )] = value;
+std::vector<std::pair<pappso::pappso_double, size_t>> Utils::getHistogram(std::vector<pappso::pappso_double> data_values, unsigned int number_of_class) {
+    std::vector<std::pair<pappso::pappso_double, size_t>> histogram(number_of_class);
+    try {
+        qDebug() << "Utils::getHistogram begin";
+
+        std::sort(data_values.begin(), data_values.end());
+        pappso::pappso_double min = *data_values.begin();
+        pappso::pappso_double max = *(data_values.end()-1);
+        pappso::pappso_double total = std::abs(max-min);
+        pappso::pappso_double offset = (total/ (pappso::pappso_double) number_of_class);
+        qDebug() << "Utils::getHistogram number_of_class offset=" << offset;
+        for (unsigned int i= 0; i < histogram.size(); i++) {
+            histogram[i] = std::pair<pappso::pappso_double, size_t> {(min + (offset * i) + (offset/2)), 0};
+        }
+        qDebug() << "Utils::getHistogram data_values";
+        for (pappso::pappso_double value :data_values) {
+            qDebug() << "Utils::getHistogram value=" << value;
+            unsigned int i = std::abs((min+(min-value))/offset );
+            qDebug() << "Utils::getHistogram i=" << i << " size=" << histogram.size();
+            histogram.at(i).second++; 
+        }
     }
-
+    catch (std::exception exception_std) {
+        throw pappso::PappsoException(QObject::tr("Utils::getHistogram error %1").arg(exception_std.what()));
+    }
+    qDebug() << "Utils::getHistogram end";
     return histogram;
 }
 
diff --git a/src/utils/utils.h b/src/utils/utils.h
index 2c17e8f21..09e851862 100644
--- a/src/utils/utils.h
+++ b/src/utils/utils.h
@@ -35,7 +35,7 @@ public:
     static const QString getDatabaseName(ExternalDatabase database);
     static const QString getXmlDouble(pappso::pappso_double number);
     static pappso::AaModificationP guessAaModificationPbyMonoisotopicMassDelta(pappso::mz mass);
-    static std::vector<size_t> getHistogram(std::vector<pappso::pappso_double> data_values, unsigned int number_of_class);
+    static std::vector<std::pair<pappso::pappso_double, size_t>> getHistogram(std::vector<pappso::pappso_double> data_values, unsigned int number_of_class);
 
 };
 
-- 
GitLab