# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'C:\Users\admin_gcueff\PycharmProjects\test_gui\test_gui4.ui'
#
# Created by: PyQt5 UI code generator 5.15.1
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import (QApplication, QWidget, QFileDialog, QTextEdit, QPushButton, QLabel, QVBoxLayout,
                             QTableView, QHBoxLayout, QLineEdit)
from PyQt5.QtCore import QDir, Qt, QAbstractTableModel
import pandas as pd
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from pyqtgraph import PlotWidget

import numpy as np

import matplotlib.pyplot as plt


import matplotlib
import scipy

from scipy.optimize import curve_fit

import warnings

from scipy.integrate import quad

import pingouin as pg


class DataFrameModel(QtCore.QAbstractTableModel):
    DtypeRole = QtCore.Qt.UserRole + 1000
    ValueRole = QtCore.Qt.UserRole + 1001

    def __init__(self, df=pd.DataFrame(), parent=None):
        super(DataFrameModel, self).__init__(parent)
        self._dataframe = df

    def setDataFrame(self, dataframe):
        self.beginResetModel()
        self._dataframe = dataframe.copy()
        self.endResetModel()

    def dataFrame(self):
        return self._dataframe

    dataFrame = QtCore.pyqtProperty(pd.DataFrame, fget=dataFrame, fset=setDataFrame)

    @QtCore.pyqtSlot(int, QtCore.Qt.Orientation, result=str)
    def headerData(self, section: int, orientation: QtCore.Qt.Orientation, role: int = QtCore.Qt.DisplayRole):
        if role == QtCore.Qt.DisplayRole:
            if orientation == QtCore.Qt.Horizontal:
                return self._dataframe.columns[section]
            else:
                return str(self._dataframe.index[section])
        return QtCore.QVariant()

    def rowCount(self, parent=QtCore.QModelIndex()):
        if parent.isValid():
            return 0
        return len(self._dataframe.index)

    def columnCount(self, parent=QtCore.QModelIndex()):
        if parent.isValid():
            return 0
        return self._dataframe.columns.size

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if not index.isValid() or not (0 <= index.row() < self.rowCount() \
                                       and 0 <= index.column() < self.columnCount()):
            return QtCore.QVariant()
        row = self._dataframe.index[index.row()]
        col = self._dataframe.columns[index.column()]
        dt = self._dataframe[col].dtype

        val = self._dataframe.iloc[row][col]
        if role == QtCore.Qt.DisplayRole:
            return str(val)
        elif role == DataFrameModel.ValueRole:
            return val
        if role == DataFrameModel.DtypeRole:
            return dt
        return QtCore.QVariant()

    def roleNames(self):
        roles = {
            QtCore.Qt.DisplayRole: b'display',
            DataFrameModel.DtypeRole: b'dtype',
            DataFrameModel.ValueRole: b'value'
        }
        return roles

class TableModel(QtCore.QAbstractTableModel):
        def __init__(self, data):
            super(TableModel, self).__init__()
            self._data = data

        def data(self, index, role):
            if role == Qt.DisplayRole:
                # See below for the nested-list data structure.
                # .row() indexes into the outer list,
                # .column() indexes into the sub-list
                return self._data[index.row()][index.column()]

        def rowCount(self, index):
            # The length of the outer list.
            return len(self._data)

        def columnCount(self, index):
            # The following takes the first sub-list, and returns
            # the length (only works if all rows are an equal length)
            return len(self._data[0])
    
    


class Ui_MainWindow(object):


    def setupUi(self, MainWindow):
        
        # fenêtre principale
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1650, 1200)
        # MainWindow.setStyleSheet("background-color: yellow;")
        
        # objet graphique principal = fond
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        # bouton 1
        self.button1 = QtWidgets.QPushButton(self.centralwidget)
        self.button1.setGeometry(QtCore.QRect(320, 60, 221, 101))
        font = QtGui.QFont()
        font.setPointSize(14)
        self.button1.setFont(font)
        self.button1.setObjectName("button1")


        self.button1.clicked.connect(self.btn_clk)

        # label
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(600, 300, 100, 20))
        self.label.setObjectName("label")



        # zone d'affichage de tables
        self.tableView = QtWidgets.QTableView(self.centralwidget)
        self.tableView.setGeometry(QtCore.QRect(320, 335, 1001, 300))
        self.tableView.setObjectName("tableView")
        self.tableView.setStyleSheet("background-color: lightgrey;")
        # self.tableView.setSortingEnabled(True)


        # zone d'affichage de texte (Text Browser)

        # self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
        # self.textBrowser.setGeometry(QtCore.QRect(1320, 300, 500, 300))
        # self.textBrowser.setObjectName("textBrowser")

        # bouton2
        self.button2 = QtWidgets.QPushButton(self.centralwidget)
        self.button2.setGeometry(QtCore.QRect(600, 60, 221, 101))
        font = QtGui.QFont()
        font.setPointSize(14)
        self.button2.setFont(font)
        self.button2.setObjectName("button2")

        self.button2.clicked.connect(self.btn_clk2)

        # bouton3
        self.button3 = QtWidgets.QPushButton(self.centralwidget)
        self.button3.setGeometry(QtCore.QRect(850, 60, 221, 101))
        font = QtGui.QFont()
        font.setPointSize(14)
        self.button3.setFont(font)
        self.button3.setObjectName("button3")

        self.button3.clicked.connect(self.btn_clk3)

        # bouton4
        self.button4 = QtWidgets.QPushButton(self.centralwidget)
        self.button4.setGeometry(QtCore.QRect(1100, 60, 221, 101))
        font = QtGui.QFont()
        font.setPointSize(14)
        self.button4.setFont(font)
        self.button4.setObjectName("button4")

        self.button4.clicked.connect(self.btn_clk4)

        # bouton4bis
        self.button4bis = QtWidgets.QPushButton(self.centralwidget)
        self.button4bis.setGeometry(QtCore.QRect(1100, 175, 221, 101))
        font = QtGui.QFont()
        font.setPointSize(14)
        self.button4bis.setFont(font)
        self.button4bis.setObjectName("button4bis")

        self.button4bis.clicked.connect(self.btn_clk4bis)

        # bouton5
        self.button5 = QtWidgets.QPushButton(self.centralwidget)
        self.button5.setGeometry(QtCore.QRect(320, 700, 221, 101))
        font = QtGui.QFont()
        font.setPointSize(14)
        self.button5.setFont(font)
        self.button5.setObjectName("button5")

        self.button5.clicked.connect(self.btn_clk5)
        
        # bouton6
        self.button6 = QtWidgets.QPushButton(self.centralwidget)
        self.button6.setGeometry(QtCore.QRect(600, 700, 221, 101))
        font = QtGui.QFont()
        font.setPointSize(14)
        self.button6.setFont(font)
        self.button6.setObjectName("button6")

        self.button6.clicked.connect(self.btn_clk6)

        # bouton7
        self.button7 = QtWidgets.QPushButton(self.centralwidget)
        self.button7.setGeometry(QtCore.QRect(600, 815, 221, 101))
        font = QtGui.QFont()
        font.setPointSize(14)
        self.button7.setFont(font)
        self.button7.setObjectName("button7")

        self.button7.clicked.connect(self.btn_clk7)
        
        # bouton8
        self.button8 = QtWidgets.QPushButton(self.centralwidget)
        self.button8.setGeometry(QtCore.QRect(600, 930, 221, 101))
        font = QtGui.QFont()
        font.setPointSize(14)
        self.button8.setFont(font)
        self.button8.setObjectName("button8")

        self.button8.clicked.connect(self.btn_clk8)

        # bouton9
        self.button9 = QtWidgets.QPushButton(self.centralwidget)
        self.button9.setGeometry(QtCore.QRect(850, 700, 221, 101))
        font = QtGui.QFont()
        font.setPointSize(14)
        self.button9.setFont(font)
        self.button9.setObjectName("button9")

        self.button9.clicked.connect(self.btn_clk9)

        # bouton10
        self.button10 = QtWidgets.QPushButton(self.centralwidget)
        self.button10.setGeometry(QtCore.QRect(850, 815, 221, 101))
        font = QtGui.QFont()
        font.setPointSize(14)
        self.button10.setFont(font)
        self.button10.setObjectName("button10")

        self.button10.clicked.connect(self.btn_clk10)

        # bouton11
        self.button11 = QtWidgets.QPushButton(self.centralwidget)
        self.button11.setGeometry(QtCore.QRect(850, 930, 221, 101))
        font = QtGui.QFont()
        font.setPointSize(14)
        self.button11.setFont(font)
        self.button11.setObjectName("button11")

        self.button11.clicked.connect(self.btn_clk11)

        # bouton12
        self.button12 = QtWidgets.QPushButton(self.centralwidget)
        self.button12.setGeometry(QtCore.QRect(1100, 700, 221, 101))
        font = QtGui.QFont()
        font.setPointSize(14)
        self.button12.setFont(font)
        self.button12.setObjectName("button12")

        self.button12.clicked.connect(self.btn_clk12)


        # bouton13
        self.button13 = QtWidgets.QPushButton(self.centralwidget)
        self.button13.setGeometry(QtCore.QRect(1100, 815, 221, 101))
        font = QtGui.QFont()
        font.setPointSize(14)
        self.button13.setFont(font)
        self.button13.setObjectName("button13")

        self.button13.clicked.connect(self.btn_clk13)

        # bouton14
        self.button14 = QtWidgets.QPushButton(self.centralwidget)
        self.button14.setGeometry(QtCore.QRect(1100, 930, 221, 101))
        font = QtGui.QFont()
        font.setPointSize(14)
        self.button14.setFont(font)
        self.button14.setObjectName("button14")

        self.button14.clicked.connect(self.btn_clk14)


        # barres de menu et d'état
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 903, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
    
    # labelling de l'interface
    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "PyG"))
        self.button1.setText(_translate("MainWindow", "1\nimport données"))
        self.label.setText(_translate("MainWindow", "fichier"))
        self.button2.setText(_translate("MainWindow", "2\ncomptages bruts"))
        self.button3.setText(_translate("MainWindow", "3\npourcentage"))
        self.button4.setText(_translate("MainWindow", "4\nplot echantillons"))
        self.button4bis.setText(_translate("MainWindow", "plot groupes"))
        self.button5.setText(_translate("MainWindow", "5\najustement"))
        self.button6.setText(_translate("MainWindow", "6\nboxplot-Gmax"))
        self.button7.setText(_translate("MainWindow", "boxplot-t50"))
        self.button8.setText(_translate("MainWindow", "boxplot-AUC"))
        self.button9.setText(_translate("MainWindow", "7\nanova-Gmax"))
        self.button10.setText(_translate("MainWindow", "anova-t50"))
        self.button11.setText(_translate("MainWindow", "anova-AUC"))
        self.button12.setText(_translate("MainWindow", "8\nmultcomp-Gmax"))
        self.button13.setText(_translate("MainWindow", "multcomp-t50"))
        self.button14.setText(_translate("MainWindow", "multcomp-AUC"))

    # fonctions utiles au fonctionnement de l'interface : c'est là qu'elle devient opérante
    
    def update(self):
        self.label.adjustSize()

    def ajustement(self):

        def hill_function(x, a, b, c, yo):
            return yo + (a * np.power(x, b) / (np.power(c, b) + np.power(x, b)))

        def optimized_hill_function(x):
            return fittedParameters[3] + (fittedParameters[0] * np.power(x, fittedParameters[1]) / (np.power(fittedParameters[2], fittedParameters[1]) + np.power(x, fittedParameters[1])))

        self.df4=pd.DataFrame()

        xData = self.ts
        initialParameters = np.array([70, 1, 30, 0])
        x_min = 0
        x_max = 54


        for i in range(0, self.df2.shape[0]):

            yData= np.array(self.df2.iloc[i,:])

            fittedParameters, pcov = curve_fit(hill_function, xData, yData, initialParameters)

            res_integrale, err_integrale = quad(optimized_hill_function, x_min, x_max)

            Gmax, t50, AUC = round(fittedParameters[0],2), round(fittedParameters[2],2), round(res_integrale,2)

            vec = [Gmax, t50, AUC]

            vec = pd.DataFrame(vec).transpose()

            self.df4 = self.df4.append(vec, ignore_index=True)

        self.df4.columns = ['Gmax','t50','AUC']

        self.df4['groupe'] = ['G1', 'G1', 'G1', 'G2', 'G2', 'G2', 'G3', 'G3', 'G3']

        model = DataFrameModel(self.df4)        
        self.tableView.setModel(model)



    def btn_clk(self):

        dialog = QFileDialog()
        dialog.setFileMode(QFileDialog.AnyFile)
        dialog.setFilter(QDir.Files)

        if dialog.exec_():
            self.file_name = dialog.selectedFiles()[0]

        self.label.setText(self.file_name)
        self.update()

        self.data = pd.read_csv(self.file_name, sep=";")
        model = DataFrameModel(self.data)
        self.tableView.setModel(model)

    def btn_clk2(self):
        self.df = self.data.drop(['ech', 'groupe', 'total'], 1)
        model = DataFrameModel(self.df)
        self.tableView.setModel(model)

    def btn_clk3(self):
        self.toto = self.data['total']

        self.df2 = pd.DataFrame()

        for i in range(0, self.df.shape[0]):
            vec = self.df.iloc[i, :]
            vec2 = round((vec / self.toto[i]) * 100, 1)
            vec2 = pd.DataFrame(vec2).transpose()
            self.df2 = pd.concat([self.df2, vec2])

        model = DataFrameModel(self.df2)
        self.tableView.setModel(model)

        self.ts = [0,8,24,26,28,30,32,34,50,54]
        self.df3 = self.df2.transpose()


    def btn_clk4 (self):
        for i in range(0, self.df3.shape[1]):
            x = np.array(self.ts)
            y = self.df3.iloc[:,i]
            plt.plot(x, y)
        # plt.pause(0.001)
        plt.show()
        plt.figure()



    def btn_clk4bis (self):

        list_df= [self.df2,self.data['groupe']]

        self.df5 = pd.concat(list_df, axis=1, ignore_index=False)

        self.df2_mean = pd.DataFrame()

        for name in self.df5.columns[0:-1]:
            vec = self.df5.groupby('groupe')[name].mean().values
            vec = pd.DataFrame(vec)
            self.df2_mean = pd.concat([self.df2_mean, vec], axis=1, ignore_index=True)

        self.df2_sd = pd.DataFrame()

        for name in self.df5.columns[0:-1]:
            vec = self.df5.groupby('groupe')[name].std().values
            vec = pd.DataFrame(vec)
            self.df2_sd = pd.concat([self.df2_sd, vec], axis=1, ignore_index=True)

        for i in range(0, self.df2_mean.shape[0]):
            plt.errorbar(np.array(self.ts), self.df2_mean.iloc[i, :], self.df2_sd.iloc[i, :], linestyle='solid', marker='.')
        # plt.pause(0.001)
        plt.show()


    def btn_clk5(self):

        self.ajustement()
        self.tableView.resizeColumnsToContents()

    def btn_clk6(self):

        boxplot = self.df4.boxplot(column='Gmax', by='groupe', grid=False)
        # plt.pause(0.001)
        plt.show(boxplot)




    def btn_clk7(self):

        boxplot = self.df4.boxplot(column='t50', by='groupe', grid=False)
        # plt.pause(0.001)
        plt.show(boxplot)

    def btn_clk8(self):

        boxplot = self.df4.boxplot(column='AUC', by='groupe', grid=False)
        # plt.pause(0.001)
        plt.show(boxplot)


    def btn_clk9(self):

        aov = pg.anova(data=self.df4, dv='Gmax', between='groupe', detailed=True).round(6)

        aov_res = pd.DataFrame(aov.T).transpose()
        model = DataFrameModel(aov_res)
        self.tableView.setModel(model)
        self.tableView.resizeColumnsToContents()



    def btn_clk10(self):

        aov = pg.anova(data=self.df4, dv='t50', between='groupe', detailed=True).round(6)

        aov_res = pd.DataFrame(aov.T).transpose()
        model = DataFrameModel(aov_res)
        self.tableView.setModel(model)
        self.tableView.resizeColumnsToContents()

    def btn_clk11(self):

        aov = pg.anova(data=self.df4, dv='AUC', between='groupe', detailed=True).round(6)

        aov_res = pd.DataFrame(aov.T).transpose()
        model = DataFrameModel(aov_res)
        self.tableView.setModel(model)
        self.tableView.resizeColumnsToContents()

    def btn_clk12(self):

        posthoc = pg.pairwise_ttests(data=self.df4, dv='Gmax', within='groupe',parametric=True, padjust='fdr_bh', effsize='hedges').round(6)

        posthoc_res = pd.DataFrame(posthoc.T).transpose()
        model = DataFrameModel(posthoc_res)
        self.tableView.setModel(model)
        self.tableView.resizeColumnsToContents()

    def btn_clk13(self):

        posthoc = pg.pairwise_ttests(data=self.df4, dv='t50', within='groupe', parametric=True, padjust='fdr_bh',
                                     effsize='hedges').round(6)

        posthoc_res = pd.DataFrame(posthoc.T).transpose()
        model = DataFrameModel(posthoc_res)
        self.tableView.setModel(model)
        self.tableView.resizeColumnsToContents()

    def btn_clk14(self):

        posthoc = pg.pairwise_ttests(data=self.df4, dv='AUC', within='groupe', parametric=True, padjust='fdr_bh',
                                     effsize='hedges').round(6)

        posthoc_res = pd.DataFrame(posthoc.T).transpose()
        model = DataFrameModel(posthoc_res)
        self.tableView.setModel(model)
        self.tableView.resizeColumnsToContents()


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)

    # PyQt5 style dispo = ['Breeze', 'Oxygen', 'QtCurve', 'Windows', 'Fusion']
    # "Plastique", "Cleanlooks", "CDE", "Motif", "GTK+"
    app.setStyle('Fusion')

    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

##

