# coding: latin-1
from astropy.io import ascii

from docutils.nodes import table
from numpy import random
import matplotlib
matplotlib.use("Qt4Agg")

__author__ = 'giovanirech'
import sys
import numpy as np
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
import visa
import os
from PyQt4 import QtCore, QtGui
from interface import Ui_MainWindow, _fromUtf8

class StartQT4(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(StartQT4, self).__init__(parent)
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.showMaximized()
        # Conexao de elementos da interface grafica
        self.fig = plt.figure()
        self.canvas = FigureCanvas(self.fig)
        self.toolbar = NavigationToolbar(self.canvas, self)
        #QtCore.QObject.connect(self.ui.btn_runpoint, QtCore.SIGNAL('clicked()'), self.dynamic_analysis)
        QtCore.QObject.connect(self.ui.btn_detectar, QtCore.SIGNAL('clicked()'), self.instrument_detection)
        QtCore.QObject.connect(self.ui.btn_conectar, QtCore.SIGNAL('clicked()'), self.instrument_connection)
        QtCore.QObject.connect(self.ui.btn_opencal, QtCore.SIGNAL('clicked()'), self.open_calibration)
        QtCore.QObject.connect(self.ui.btn_shortcal, QtCore.SIGNAL('clicked()'), self.short_calibration)
        QtCore.QObject.connect(self.ui.btn_run, QtCore.SIGNAL('clicked()'), self.run_analysis)
        QtCore.QObject.connect(self.ui.toolbtn_savepath, QtCore.SIGNAL('clicked()'), self.get_save_path)
        QtCore.QObject.connect(self.ui.btn_plot, QtCore.SIGNAL('clicked()'), self.plot_test)
        QtCore.QObject.connect(self.ui.btn_plot_permi, QtCore.SIGNAL('clicked()'), self.plot_erei)
        QtCore.QObject.connect(self.ui.btn_plot_RC, QtCore.SIGNAL('clicked()'), self.plot_RC)
        QtCore.QObject.connect(self.ui.btn_plot_ZT, QtCore.SIGNAL('clicked()'), self.plot_ZT)
        QtCore.QObject.connect(self.ui.btn_plot_ZrZi, QtCore.SIGNAL('clicked()'), self.plot_ZrZi)
        QtCore.QObject.connect(self.ui.actionImportar_Dados, QtCore.SIGNAL('triggered()'), self.importar_dados)
        QtCore.QObject.connect(self.ui.blt_skipcal, QtCore.SIGNAL('clicked()'), self.skip_calibration)
        self.is_open_calibrated = False
        self.is_short_calibrated = False
        layout = self.ui.verticalLayout
        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)

    # Metodos
    def skip_calibration(self):
        warning = QtGui.QMessageBox()
        warning.setText('Are you sure you want to skip calibration? Without geometry compensation, the collected data'
                        'may be contaminated with the effect of resistivity and capacitance of the accessories, cables and conections.')
        warning.setIcon(QtGui.QMessageBox.Warning)
        warning.addButton('Continue', QtGui.QMessageBox.AcceptRole)
        warning.addButton('Cancel', QtGui.QMessageBox.RejectRole)
        warning.exec_()
        btnclicked = warning.clickedButton().text()
        if btnclicked == 'Continue':
            self.ui.groupBox_analise.setEnabled(True)
            self.ui.groupBox__amostra.setEnabled(True)
            self.ui.btn_run.setEnabled(True)
        else:
            pass

    def importar_dados(self):
        caminho = QtGui.QFileDialog.getOpenFileNameAndFilter(self, 'Select the file', filter='*.txt')
        s = str(caminho[0]).rsplit('/', 1)
        path = s[0]+'/'
        data = np.genfromtxt(str(caminho[0]), skip_header=0)[:, :]
        amostra = 'Identifiction not found'
        diametro = 1
        espessura = 1
        with open(str(caminho[0])) as arquivo:
            for line in arquivo:
                if line.startswith('#D'):
                    diametro = float(line.rstrip('\n').split()[-1])
                if line.startswith('#d'):
                    espessura = float(line.rstrip('\n').split()[-1])
                if line.startswith('#sample'):
                    amostra = ' '.join(line.rstrip('\n').split()[1:-1])
                if line.startswith('#sweep'):
                    if line.rstrip('\n').split()[-1].lower == 'lin':
                        self.ui.var_lin.setChecked(True)
                    else:
                        self.ui.var_log.setChecked(True)
        global Zr, Zi, R, C, er, ei, d, D, Theta, Freq, Z
        nop = len(data[:, 0])
        Freq = data[:, 0]
        Z = data[:, 1]
        Theta = data[:, 2]
        e0 = 8.85418782e-12
        d = espessura*10**(-3)
        D = diametro*10**(-3)
        # er = (2*d*np.cos(np.asarray(Theta)*np.pi/180))/(e0*np.asarray(Z)*np.asarray(Freq)*(D**2)*(np.pi*np.pi)*np.tan(np.asarray(Theta)*np.pi/180))
        A = (np.pi*(D**2))/4
        Zr = Z*np.cos(np.asarray(Theta)*np.pi/180)
        Zi = Z*np.sin(np.asarray(Theta)*np.pi/180)*(-1)
        R = Z/np.cos(np.asarray(Theta)*np.pi/180)
        C = Zi/(Zr*np.asarray(Freq)*R*2*np.pi)

        er = (C*d)/(e0*A)
        ei = er*np.tan((90+np.asarray(Theta))*np.pi/180)
        # ei = er*np.tan((90+np.asarray(Theta))*np.pi/180
        self.ui.btn_plot_ZrZi.setEnabled(True)
        self.ui.btn_plot_ZT.setEnabled(True)
        self.ui.btn_plot_permi.setEnabled(True)
        self.ui.btn_plot_RC.setEnabled(True)
        self.ui.groupBox__amostra.setEnabled(True)
        self.ui.groupBox_analise.setEnabled(True)
        self.ui.amostra_id.setText(amostra)
        self.ui.LineEdit_SavePath.setText(path)
        self.ui.tbox_diametro.setText(str(diametro))
        self.ui.tbox_espessura.setText(str(espessura))
        self.ui.spin_freq_inicial.setValue(int(Freq[0]))
        self.ui.spin_freq_final.setValue(int(Freq[-1]))
        self.ui.num_pontos.setValue(int(nop))
        self.plot_erei()
        self.update_table(np.ndarray.tolist(Freq), np.ndarray.tolist(Z), np.ndarray.tolist(Theta),
                          np.ndarray.tolist(er), np.ndarray.tolist(ei))

    def instrument_detection(self):
        global rm
        is_simulation = self.ui.checkbox_pyvisasim.checkState()
        if is_simulation:
            rm = visa.ResourceManager('@sim')
        else:
            rm = visa.ResourceManager()
        equipaments = list(rm.list_resources())
        self.ui.combobox_equipamentos.addItems(equipaments)

    def instrument_connection(self):
        global instrument
        address = self.ui.combobox_equipamentos.currentText()
        try:
            instrument = rm.open_resource(unicode(address))
        except:
            message = QtGui.QMessageBox()
            message.setText('Conection error.')
            message.setDetailedText('Please, verify that the equipament is turned on and connected to the computer.'
                                     'Make sure that the conection cable is working and you have installed all the necessary drivers.')
            message.exec_()
            return
        instrument_name = instrument.query('*IDN?')
        self.ui.label_inst_name.setText(instrument_name)
        self.ui.group_calibration.setEnabled(True)

    def open_calibration(self):
        instrument.write('HOLD')
        warning = QtGui.QMessageBox()
        warning.setText('Please, set the accessory to the OPEN configuration')
        warning.setIcon(QtGui.QMessageBox.Information)
        warning.addButton('Continue', QtGui.QMessageBox.AcceptRole)
        warning.addButton('Cancel', QtGui.QMessageBox.RejectRole)
        warning.exec_()
        response = warning.clickedButton().text()
        if response == 'Continue':
            instrument.write('E4TP OFF')
            instrument.write('TRGS INT')
            instrument.write('ESNB 1')
            instrument.write('*SRE 4')
            instrument.write('*CLS')
            instrument.write('COMA')
            del instrument.timeout
            instrument.write('*WAI')
            instrument.ask('*OPC?')
            complete = QtGui.QMessageBox()
            complete.setText('OPEN compensation complete.')
            complete.setIcon(QtGui.QMessageBox.Information)
            complete.addButton('OK', QtGui.QMessageBox.AcceptRole)
            complete.exec_()
            self.is_open_calibrated = True
            if self.is_open_calibrated and self.is_short_calibrated:
                self.ui.groupBox_analise.setEnabled(True)
                self.ui.groupBox__amostra.setEnabled(True)
                self.ui.btn_run.setEnabled(True)
        else:
            pass

    def short_calibration(self):
        instrument.write('HOLD')
        warning = QtGui.QMessageBox()
        warning.setText('Please, set the accessory to the SHORT configuration')
        warning.setIcon(QtGui.QMessageBox.Information)
        warning.addButton('Continue', QtGui.QMessageBox.AcceptRole)
        warning.addButton('Cancel', QtGui.QMessageBox.RejectRole)
        warning.exec_()
        response = warning.clickedButton().text()
        if response == 'Continue':
            instrument.write('E4TP OFF')
            instrument.write('TRGS INT')
            instrument.write('ESNB 1')
            instrument.write('*SRE 4')
            instrument.write('*CLS')
            instrument.write('COMB')
            del instrument.timeout
            instrument.write('*WAI')
            instrument.ask('*OPC?')
            complete = QtGui.QMessageBox()
            complete.setText('SHORT compensation complete.')
            complete.setIcon(QtGui.QMessageBox.Information)
            complete.addButton('OK', QtGui.QMessageBox.AcceptRole)
            complete.exec_()
            self.is_short_calibrated = True
            if self.is_open_calibrated and self.is_short_calibrated:
                self.ui.groupBox_analise.setEnabled(True)
                self.ui.groupBox__amostra.setEnabled(True)
                self.ui.btn_run.setEnabled(True)
        else:
            pass

    def get_save_path(self):
        path = QtGui.QFileDialog.getExistingDirectory(self, 'Select destination folder')
        self.ui.LineEdit_SavePath.setText(path)

    def no_blank_fields(self):
        if str(self.ui.amostra_id.text()) == '':
            warning = QtGui.QMessageBox()
            warning.setIcon(QtGui.QMessageBox.Warning)
            warning.setText('You need t provide a identification to your sample.')
            warning.addButton('Ok', QtGui.QMessageBox.AcceptRole)
            warning.exec_()
            self.ui.amostra_id.hasFocus()
            return False
        if str(self.ui.LineEdit_SavePath.text()) == '':
            warning = QtGui.QMessageBox()
            warning.setIcon(QtGui.QMessageBox.Warning)
            warning.setText('Select a destination folder to save the colected data.')
            warning.addButton('Ok', QtGui.QMessageBox.AcceptRole)
            warning.exec_()
            return False
        if str(self.ui.tbox_diametro.text()) == '' or str(self.ui.tbox_espessura.text()) == '':
            warning = QtGui.QMessageBox()
            warning.setIcon(QtGui.QMessageBox.Warning)
            warning.setText('You need to provide the sample dimensions for permittivity and capacitance computations')
            warning.addButton('Ok', QtGui.QMessageBox.AcceptRole)
            warning.exec_()
            self.ui.tbox_diametro.hasFocus()
            return False
        return True

    def run_analysis(self):
        try:
            instrument
        except NameError:
            errorbox = QtGui.QMessageBox()
            errorbox.setIcon(QtGui.QMessageBox.Critical)
            errorbox.setText('Instrument no recognized or not connected.')
            errorbox.addButton('Ok', QtGui.QMessageBox.AcceptRole)
            errorbox.exec_()
        if not(self.no_blank_fields()):
            return
        if self.ui.var_lin.isChecked():
            sweepcmd = 'LIN'
        else:
            sweepcmd = 'LOG'

        if self.ui.checkbox_ptavg.isChecked():
            paver = 'ON'
        else:
            paver = 'OFF'
        id_amostra = self.ui.amostra_id.text()
        diametro = float(self.ui.tbox_diametro.text())
        espessura = float(self.ui.tbox_espessura.text())
        instrument.write('STAR %s' %self.ui.spin_freq_inicial.value())
        instrument.write('STOP %s' %self.ui.spin_freq_final.value())
        instrument.write('POIN %s' %self.ui.num_pontos.value())
        instrument.write('POWMOD VOLT')
        instrument.write('POWE %s' %self.ui.spinbox_tensao.value())
        instrument.write('SWPT %s' %sweepcmd)
        instrument.write('BWFACT %s' %self.ui.spinbox_banda.value())
        instrument.write('PAVERFACT %s' %self.ui.spin_ptavg.value())
        instrument.write('PAVER %s' %paver)
        instrument.write('MEASTAT %s' %paver)
        instrument.write('MEAS IMPH')
        instrument.write('SING')
        instrument.write('TRGS INT')
        instrument.write('ESNB 1')
        instrument.write('*SRE 4')
        instrument.write('*CLS')
        del instrument.timeout
        instrument.write('*WAI')
        instrument.ask('*OPC?')
        instrument.write('TRAC A')
        instrument.write('AUTO')
        instrument.write('TRAC B')
        instrument.write('AUTO')
        global Zr, Zi, R, C, er, ei, d, D, Theta, Freq, Z
        instrument.write('FORM5')
        instrument.write('TRAC A')
        nop = instrument.ask('POIN?')
        Z_data = instrument.ask_for_values('OUTPDTRC?')
        Z = range(int(nop))
        for x in range(0, int(nop)):
            Z[x] = Z_data[2*x]
        instrument.write('TRAC B')
        Theta_data = instrument.ask_for_values('OUTPDTRC?')
        Theta = range(int(nop))
        for x in range(0, int(nop)):
            Theta[x] = Theta_data[2*x]
        Freq = instrument.ask_for_values('OUTPSWPRM?')
        #stats = instrument.ask_for_values('MEASTAT?')
        e0 = 8.85418782e-12
        d = espessura*10**(-3)
        D = diametro*10**(-3)
        # er = (2*d*np.cos(np.asarray(Theta)*np.pi/180))/(e0*np.asarray(Z)*np.asarray(Freq)*(D**2)*(np.pi*np.pi)*np.tan(np.asarray(Theta)*np.pi/180))
        A = (np.pi*(D**2))/4
        Zr = Z*np.cos(np.asarray(Theta)*np.pi/180)
        Zi = Z*np.sin(np.asarray(Theta)*np.pi/180)*(-1)
        R = Z/np.cos(np.asarray(Theta)*np.pi/180)
        C = Zi/(Zr*np.asarray(Freq)*R*2*np.pi)

        er = (C*d)/(e0*A)
        ei = er*np.tan((90+np.asarray(Theta))*np.pi/180)
        # ei = er*np.tan((90+np.asarray(Theta))*np.pi/180
        self.plot_erei()
        self.update_table(Freq, Z, Theta, np.ndarray.tolist(er), np.ndarray.tolist(ei))
        path = str(self.ui.LineEdit_SavePath.text())
        filename = str(id_amostra)
        M = np.c_[np.asarray(Freq), np.asarray(Z), np.asarray(Theta), er, ei]
        np.savetxt('%s\%s.txt' % (path, filename), M, fmt='%1.4e',
                   delimiter='\t',
                   header='#Freq(Hz)\t Z(ohms)\t Phase(degrees) \t er_Re \t er_Im',
                   comments='#Sample %s\n#d(mm)  %s\n#D(mm) %s \n#Sweep  %s \n#Voltage  %s'
                            % (id_amostra, espessura, diametro, sweepcmd, self.ui.spinbox_tensao.value()))
        self.ui.btn_plot_ZrZi.setEnabled(True)
        self.ui.btn_plot_ZT.setEnabled(True)
        self.ui.btn_plot_permi.setEnabled(True)
        self.ui.btn_plot_RC.setEnabled(True)

    def dynamic_analysis(self):
        #message = QtGui.QMessageBox()
        #message.setText('Fun\E7\E3o ainda em constru\E7\E3o.')
        #message.setDetailedText('Por favor, utilize o modo padr\E3o de an\E1lise por enquanto.')
        #message.exec_()
        #return
        try:
            instrument
        except NameError:
            errorbox = QtGui.QMessageBox()
            errorbox.setIcon(QtGui.QMessageBox.Critical)
            errorbox.setText('Instrument not connected or not recognized.')
            errorbox.addButton('Ok', QtGui.QMessageBox.AcceptRole)
            errorbox.exec_()
        if not(self.no_blank_fields()):
            return
        if self.ui.var_lin.isChecked():
            sweepcmd = 'LIN'
        else:
            sweepcmd = 'LOG'

        if self.ui.checkbox_ptavg.isChecked():
            paver = 'ON'
        else:
            paver = 'OFF'
        id_amostra = self.ui.amostra_id.text()
        diametro = float(self.ui.tbox_diametro.text())
        espessura = float(self.ui.tbox_espessura.text())
        instrument.write('STAR %s' %self.ui.spin_freq_inicial.value())
        instrument.write('STOP %s' %self.ui.spin_freq_final.value())
        instrument.write('POIN %s' %self.ui.num_pontos.value())
        instrument.write('POWMOD VOLT')
        instrument.write('POWE %s' %self.ui.spinbox_tensao.value())
        instrument.write('SWPT %s' %sweepcmd)
        instrument.write('BWFACT %s' %self.ui.spinbox_banda.value())
        instrument.write('PAVERFACT %s' %self.ui.spin_ptavg.value())
        instrument.write('PAVER %s' %paver)
        instrument.write('MEASTAT %s' %paver)
        instrument.write('MEAS IMPH')
        instrument.write('MAN')
        instrument.write('TRGS INT')
        instrument.write('ESNB 1')
        instrument.write('*SRE 4')
        instrument.write('*CLS')
        del instrument.timeout
        instrument.write('*WAI')
        instrument.ask('*OPC?')
        instrument.write('TRAC A')
        instrument.write('AUTO')
        instrument.write('TRAC B')
        instrument.write('AUTO')
        global Zr, Zi, R, C, er, ei, d, D, Theta, Freq, Z
        instrument.write('FORM5')
        instrument.write('TRAC A')
        nop = instrument.ask('POIN?')
        Z_data = instrument.ask_for_values('OUTPDTRC?')
        Z = range(int(nop))
        for x in range(0, int(nop)):
            Z[x] = Z_data[2*x]
        instrument.write('TRAC B')
        Theta_data = instrument.ask_for_values('OUTPDTRC?')
        Theta = range(int(nop))
        for x in range(0, int(nop)):
            Theta[x] = Theta_data[2*x]
        Freq = instrument.ask_for_values('OUTPSWPRM?')
        #stats = instrument.ask_for_values('MEASTAT?')
        e0 = 8.85418782e-12
        d = espessura*10**(-3)
        D = diametro*10**(-3)
        # er = (2*d*np.cos(np.asarray(Theta)*np.pi/180))/(e0*np.asarray(Z)*np.asarray(Freq)*(D**2)*(np.pi*np.pi)*np.tan(np.asarray(Theta)*np.pi/180))
        A = (np.pi*(D**2))/4
        Zr = Z*np.cos(np.asarray(Theta)*np.pi/180)
        Zi = Z*np.sin(np.asarray(Theta)*np.pi/180)*(-1)
        R = Z/np.cos(np.asarray(Theta)*np.pi/180)
        C = Zi/(Zr*np.asarray(Freq)*R*2*np.pi)

        er = (C*d)/(e0*A)
        ei = er*np.tan((90+np.asarray(Theta))*np.pi/180)
        # ei = er*np.tan((90+np.asarray(Theta))*np.pi/180
        self.plot_erei()
        self.update_table(Freq, Z, Theta, np.ndarray.tolist(er), np.ndarray.tolist(ei))
        path = str(self.ui.LineEdit_SavePath.text())
        filename = str(id_amostra)
        M = np.c_[np.asarray(Freq), np.asarray(Z), np.asarray(Theta), er, ei]
        np.savetxt('%s\%s.txt' % (path, filename), M, fmt='%1.4e',
                   delimiter='\t',
                   header='#Freq(Hz)\t Z(ohms)\t Phase(degrees) \t er_Re \t er_Im',
                   comments='#sample %s\n#d(mm) = %s\n#D(mm) = %s \n#sweep = %s \n#voltage = %s'
                            % (id_amostra, espessura, diametro, sweepcmd, self.ui.spinbox_tensao.value()))
        self.ui.btn_plot_ZrZi.setEnabled(True)
        self.ui.btn_plot_ZT.setEnabled(True)
        self.ui.btn_plot_permi.setEnabled(True)
        self.ui.btn_plot_RC.setEnabled(True)

        # path = str(self.ui.LineEdit_SavePath.text())
        # filename = str(id_amostra)
        # M = np.c_[np.asarray(Freq), np.asarray(Z), np.asarray(Theta), er, ei]
        # np.savetxt('%s\%s.txt' % (path, filename), M, fmt='%1.4e',
        #           delimiter='\t',
        #           header='Freq(Hz)\t Z(ohms)\t Phase(degrees) \t er_Re \t er_Im',
        #           comments='#Amostra %s\n #d = %s \n #D = %s \n' % (id_amostra, espessura, diametro))

    def plot_test(self):
        data = [random.random() for i in range(10)]

        # create an axis
        ax = self.fig.add_subplot(111)

        # discards the old graph
        ax.hold(False)

        # plot data
        ax.plot(data, '*-')

        # refresh canvas
        self.canvas.draw()
        self.update_table(data, data, data, data, data)

    def plot_erei(self):
        self.plot_data(Freq, 'Frequency (Hz)', er, '$\epsilon\'$', ei, '$\epsilon\'\'$', 'log')

    def plot_RC(self):
        self.plot_data(Freq, 'Frequency (Hz)', R, 'R (Ohms)', C, 'C (F)', 'log')

    def plot_ZT(self):
        self.plot_data(Freq, 'Frequency (Hz)', Z, 'Impedance (Ohms)', Theta, 'Phase (degrees)', 'log')

    def plot_ZrZi(self):
        self.fig.clear()
        self.ax1 = self.fig.add_subplot(111)
        self.ax1.hold(False)
        self.ax1.plot(Zr, Zi, 'blue')
        self.ax1.set_title(self.ui.amostra_id.text(), fontsize='12')
        self.ax1.grid(which='both')
        self.ax1.set_xlabel('Real Impedance', fontsize='12')
        self.ax1.set_ylabel('Imaginary Impedance', fontsize='18', color='blue')
        plt.xlim(min(Zr), max(Zr))
        self.canvas.draw()

    def plot_data(self, x, labelx, y1, labely1, y2, labely2, xscale):
        """

        :rtype : object
        """
        self.fig.hold(False)
        self.fig.clear()
        self.ax1 = self.fig.add_subplot(111)
        self.ax1.hold(False)
        self.ax1.plot(x, y1, 'blue')
        self.ax1.set_title(self.ui.amostra_id.text(), fontsize='12')
        self.ax2 = self.ax1.twinx()
        self.ax2.plot(x, y2, 'green')
        self.ax1.grid(which='both')
        self.ax1.set_xlabel(labelx, fontsize='12')
        self.ax1.set_ylabel(labely1, fontsize='18', color='blue')
        self.ax2.set_ylabel(labely2, fontsize='18', color='green')
        plt.xlim(x[0], x[-1])
        self.ax1.set_xscale(xscale)
        self.ax2.set_xscale(xscale)
        for i in self.ax1.get_yticklabels():
            i.set_color('blue')
        for i in self.ax2.get_yticklabels():
            i.set_color('green')
        # plt.savefig('%s.png' %file_name.value, dpi = 300)
        # self.ui.plot_window.
        self.canvas.draw()

    def update_table(self, freq, imped, teta, er, ei):
        data = [freq, imped, teta, er, ei]
        header = ['Frequency (Hz)', 'Impedance (Ohms)', 'Phase (deg)', 'Real Permittivity', 'Imaginary Permittivity']
        self.table_model = MyTableModel(data, header, parent=self)
        self.ui.tableView.setModel(self.table_model)
        # set row height
        nrows = len(data[0])
        for row in xrange(nrows):
            self.ui.tableView.setRowHeight(row, 18)
        for col in [1, 3, 4]:
            self.ui.tableView.resizeColumnToContents(col)

class MyTableModel(QtCore.QAbstractTableModel):
    def __init__(self, datain, headerdata, parent=None, *args):
        QtCore.QAbstractTableModel.__init__(self, parent, *args)
        self.arraydata = datain
        self.headerdata = headerdata
        self.rows = range(0, len(datain[0]))

    def rowCount(self, parent):
        return len(self.arraydata[0])

    def columnCount(self, parent):
        return len(self.arraydata)

    def data(self, index, role):
        if not index.isValid():
            return QtCore.QVariant()
        elif role != QtCore.Qt.DisplayRole:
            return QtCore.QVariant()
        return QtCore.QVariant(self.arraydata[index.column()][index.row()])

    def headerData(self, col, orientation, role):
        if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
            return QtCore.QVariant(self.headerdata[col])
        return QtCore.QVariant()

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = StartQT4()
    myapp.show()
    sys.exit(app.exec_())


import CO2_tree as co2t
import CO2Forest as co2f
import numpy
import pickle
from scipy import sparse
from sklearn.metrics import f1_score
from sklearn.metrics import accuracy_score

from sklearn.model_selection import KFold
kf = KFold(n_splits=5)

with open("titanicX.pkl","rb") as f:
    x = pickle.load(f)

with open("titanicY.pkl","rb") as f:
    y = pickle.load(f)

y = y + 1
tree_deth = [9]
sratios = [0.1]
sratios2 = [1.0]
fratios = [0.8]

C = [5000]
#C=[5000,10000]

best_v_acc = 0.

cdp = []

for d in tree_deth:
    for sratio in sratios:
        for sratio2 in sratios2:
            for fratio in fratios:
                for c in C:
                    for ns in [0.]:
                        for cov in [1 for _ in range(10000)]:
                            v_sc = []
                            v2_sc = []
                            t_scw = []
                            t_scf = []
                            wd = []

                            covs = []
                            print ("Test carbon forest with tree deth= ", d+1, " C= ", c, " s ratio ", sratio," s ration 2" ,sratio2," f ratio ",fratio," noise=",ns, "cov=",cov)
                            for train, test in kf.split(x):

                                trc = co2f.CO2Forest(C=c, dual=False,tol = 0.0000001,max_iter=1000000,kernel='linear',max_deth=d,n_jobs=10,sample_ratio=1.0, feature_ratio = fratio,n_estimators=10,gamma=1,dropout_low=sratio,dropout_high=sratio2,noise=ns,cov_dr=cov)

                                trc.fit(sparse.csr_matrix(x[train]), y[train])

                                #Y_v = trc.predict(sparse.csr_matrix(x[test]),True)
                                Y_v_f = trc.predict(sparse.csr_matrix(x[test]),False)

                                #proba_v = trc.predict_proba(sparse.csr_matrix(x[test]),use_weight=True)
                                #proba_f = trc.predict_proba(sparse.csr_matrix(x[test]),use_weight=False)

                                covs.append(numpy.abs(trc.covs).mean())
                                #for i in range(Y_v.shape[0]):
                                #    if Y_v[i] != Y_v_f[i]:
                                #        print ("diff: ")
                                #        print(proba_v[i])
                                #        print(proba_f[i])

                                #wd.append(accuracy_score(Y_v,Y_v_f))

                                #Y_t_w = trc.predict(sparse.csr_matrix(x[train]),True)
                                Y_t_f =  trc.predict(sparse.csr_matrix(x[train]),False)
                                #print(Y_v)

                                try:
                                    #v_sc.append(f1_score(y[test],Y_v))
                                    #t_scw.append(f1_score(y[train],Y_t_w))
                                    t_scf.append(f1_score(y[train],Y_t_f))
                                    v2_sc.append(f1_score(y[test],Y_v_f))

                                except Exception as e:
                                    print("Error:", e)

                            print (v_sc)
                            #v_sc = numpy.asarray(v_sc)
                            v2_sc = numpy.asarray(v2_sc)
                            #t_scw = numpy.asarray(t_scw)
                            t_scf = numpy.asarray(t_scf)

                            #if v_sc.mean() > best_v_acc:
                            #    best_v_acc = v_sc.mean()

                            #print ("Test f1:", v_sc.mean())
                            #print ("Delta_w: ",t_scw.mean() - v_sc.mean())
                            print ("Delta_f: ",t_scf.mean() - v2_sc.mean())
                            #print ("Sim: ", numpy.asarray(wd).mean())
                            print("COVS: ",numpy.asarray(covs).mean())

                            for ij in range(len(t_scf)):
                                if covs[ij] > 0.38:
                                    cdp.append((t_scf[ij] - v2_sc[ij],covs[ij]))

#print ("Best result is:", best_v_acc)
print ("cov vs delta:",cdp)


import flask
import psycopg2
from ..authenticated_blueprint_preparator import AuthenticatedBlueprintPreparator
from .decorators import rest_endpoint

name = 'religion'
app = AuthenticatedBlueprintPreparator(name, __name__, template_folder=None)

@app.route('/religions', role=['user', 'visitor'])
@rest_endpoint
def get_all_religions(c):
    '''
    Get a hierarchy of religions.

    @returns            application/json

    This utilizes the `parent_id` attribute in the table `religion` to build a
    list of trees. The return value is an array of JSON objects. Each root node
    is a main religion, and one of its attributes is `children`, holding an
    array of children, which may again hold children, and so on.

    Each node of each tree has the following, exemplary (2020-01-09) structure:

        {
            "abbreviation": "MARO",
            "children": [ ... ],
            "color": "hsl(10, 80%, 50%)",
            "id": 3,
            "name": "Maronite Church",
            "parent_id": 98
        }
    '''
    c.execute('select * from religion')
    data = list(map(lambda x: x._asdict(), c.fetchall()))

    def append_children(parent, lst):
        children = list(filter(lambda x: x['parent_id'] == parent['id'], lst))
        parent['children'] = children
        for child in children:
            append_children(child, lst)
        return parent

    toplevel = list(map(lambda x: append_children(x, data), filter(lambda x: x['parent_id'] is None, data)))

    return flask.jsonify(toplevel)

@app.route('/religion-list', role=['user', 'visitor'])
@rest_endpoint
def get_religion_list(c):
    '''
    Get a list of religion names and IDs.

    @returns            application/json

    Example return value excerpt:

        [
          {
            "id": 1,
            "name": "Christianity",
            "parent_id": null
          },
          {
            "id": 5,
            "name": "Church of the East",
            "parent_id": 1
          },
          ...
        ]
    '''
    c.execute('select id, name, parent_id from religion')
    return flask.jsonify(list(map(lambda x: x._asdict(), c.fetchall())))


import datetime

def pretty_print(date):

    day_suffix = ''

    ones_digit = date.day%10
    tens_digit = date.day//10
    if tens_digit == 1:
        day_suffix = 'th'
    else:
        if ones_digit == 1:
            day_suffix = 'st'
        elif ones_digit == 2:
            day_suffix = 'nd'
        elif ones_digit == 3:
            day_suffix = 'rd'
        else:
            day_suffix = 'th'

    day = int(date.strftime('%d'))
    return date.strftime(f'%A, %B {day}{day_suffix} %Y')

# date = datetime.datetime.now()
date = datetime.datetime(2019, 9, 1)
for i in range(40):
    print(pretty_print(date))
    dt = datetime.timedelta(days=1)
    date += dt


'''
Representation of unit tests for answer boxes in edX-platform courses, together with a
representation of a full set of such tests for a course.
'''

import yaml
import os

class AnswerBoxUnitTest(object):
    '''
    Representation of a single unit test for an answer box.
    '''
    SPEC_FIELDS = ['url_name', 'responses', 'expected']
    def __init__(self, test_spec=None, test_name=None):
        '''
        test_spec = dict giving url_name, responses, and expected.
        test_name = name of this test (or, e.g. at least a sequential index number for the test)

        responses   = ordered list of strings, specifying user input for each input in the answer box element
        expected    = either list or single string instance of "correct" or "incorrect" or "error"
        box_indexes = list of (x,y) integer pairs specifying index number of the answer box
                      entry.  This is used to construct the input box ID, which is of the form
                      input_<url_name>_<x>_<y>, where <x> indexes which \abox the input is, and
                      <y> indexes which input element it is, within a given abox (for aboxes with
                      multiple input boxes).  This list should have the same length as the responses.
                      If box_indices is not provided, then it defaults to
                                  zip(range(len(responses)), [0]*len(responses))
                      Note that the edX platform seems to start x from 2 (and not 1, or 0), and
                      y from 1.  We stick to the convention that x and y both start at 0, and leave
                      the offsets for edxapi.
        '''
        self.url_name = None
        self.responses = []
        self.expected = []
        self.name = test_name
        self.box_indexes = []
        if test_spec:
            for field in self.SPEC_FIELDS:
                if not field in test_spec:
                    print("Missing %s from test %s" % (field, test_name))
                else:
                    setattr(self, field, test_spec[field])
            self.box_indexes = test_spec.get('box_indexes', self.box_indexes)
        if not isinstance(self.responses, list):
            raise Exception("[AnswerBoxUnitTes] illegel responses=%s -- must be list" % self.responses)
        if isinstance(self.expected, list) and not len(self.expected)==len(self.responses):
            raise Exception("[AnswerBoxUnitTes] mismatched lengths responses=%s ; expected=%s" % (self.responses, self.expected))
        if not self.box_indexes:
            self.box_indexes = list(zip(list(range(len(self.responses))), [0]*len(self.responses)))
        if not len(self.box_indexes)==len(self.responses):
            raise Exception("[AnswerBoxUnitTes] mismatched lengths responses=%s ; box_indexes=%s" % (self.responses, self.box_indexes))

    def __unicode__(self):
        return "[AnswerBoxUnitTest] url_name=%s, responses=%s, expected=%s indexes=%s (%s)" % (self.url_name,
                                                                                self.responses,
                                                                                self.expected,
                                                                                self.box_indexes,
                                                                                self.name)

    __str__ = __unicode__

    @property
    def expected_as_list(self):
        if not isinstance(self.expected, list):
            return [self.expected] * len(self.responses)
        return self.expected

    def box_indexes_plus(self, offset=1):
        '''
        Return box indexes, with the <x> coordinate incremented by offset
        '''
        return [(x+offset, y) for (x,y) in self.box_indexes]

    @property
    def box_indexes_as_list(self):
        '''
        Return box indexes, as list of lists (instead of as list of tuples).
        Needed so YAML outputs correctly.
        '''
        return [list(x) for x in self.box_indexes]

    @property
    def max_box_x_index(self):
        '''
        Return largest x index of box indexes
        '''
        return max([x[0] for x in self.box_indexes])

    def __add__(self, other):
        assert self.url_name==other.url_name
        both_responses = self.responses + other.responses
        both_expected = self.expected_as_list + other.expected_as_list
        both_name = "combination of %s and %s" % (str(self.name), str(other.name))
        both_indexes = self.box_indexes + other.box_indexes_plus(offset=self.max_box_x_index+1)
        return AnswerBoxUnitTest(dict(url_name=self.url_name,
                                      responses=both_responses,
                                      expected=both_expected,
                                      box_indexes=both_indexes,
                                      name=both_name))

    def as_dict(self):
        '''
        Return dict representation of this AnswerBoxUnitTest object
        '''
        data = dict(url_name=self.url_name, responses=self.responses, expected=self.expected,
                    box_indexes=self.box_indexes_as_list)
        if self.name:
            data['name'] = self.name
        return data

class CourseUnitTestSet(object):
    '''
    Set of tests (AnswerBoxUnitTest objecs), for an edX-platform course.
    '''
    def __init__(self, fn=None, verbose=True, yaml_string=None):
        '''
        fn = name of file to load course unit tests from (defaults to looking for YAML)
        '''
        self.config = {}
        self.tests = []
        self.verbose = verbose
        if fn or yaml_string:
            self.load_tests_from_file(fn=fn, yaml_string=yaml_string)

    def add_tests(self, tests):
        '''
        tests - list of AnswerBoxUnitTest objects
        '''
        for test in tests:
            self.add_test(test)

    def add_test(self, test):
        '''
        test - AnswerBoxUnitTest object
        '''
        if not isinstance(test, AnswerBoxUnitTest):
            raise Exception("[CourseUnitTestSet] add_test: test must be an instance of AnswerBoxUnitTest")
        self.tests.append(test)

    def output_to_file(self, ofn):
        '''
        Write test set to output file in YAML format.
        '''
        cut_spec = {'config': self.config, 'tests': [x.as_dict() for x in self.tests]}
        open(ofn, 'w').write(yaml.dump(cut_spec))

    def load_tests_from_file(self, fn=None, yaml_string=None):
        if fn:
            if not os.path.exists(fn):
                raise Exception("[CourseUnitTestSet] Expecting course unit test config file - but no such file %s" % fn)
            yaml_string = open(fn).read()
        if not yaml_string:
            raise Exception("[CourseUnitTestSet] empty YAML string %s" % yaml_string)
        cut_specs = yaml.load(yaml_string)
        if 'config' in cut_specs:
            self.config = cut_specs['config']
            # self.__dict__.update(cut_specs['config'])
        self.cut_specs = cut_specs
        cnt = 0
        for test in cut_specs.get('tests', []):
            cnt += 1
            abutest = AnswerBoxUnitTest(test, cnt)
            self.tests.append(abutest)
        self.ntests = len(self.tests)
        if self.verbose:
            print("[CourseUnitTestSet] Loaded %s answer box unit tests from %s" % (self.ntests, fn))

#-----------------------------------------------------------------------------
# unit tests

def test_abut1():
    abut1 = AnswerBoxUnitTest(dict(responses=["1"], expected="correct", url_name="x"))
    abut2 = AnswerBoxUnitTest(dict(responses=["2"], expected="incorrect", url_name="x"))
    abut3 = abut1 + abut2
    assert abut3.url_name=="x"
    assert abut3.expected==["correct", "incorrect"]
    assert abut3.responses==["1", "2"]

def test_cutset1():
    yaml = """config: {a: 2}
tests:
- expected: [correct]
  name: A problem/test_1
  responses: [red]
  url_name: a_problem
    """
    cutset = CourseUnitTestSet(yaml_string=yaml)
    assert len(cutset.tests)==1
    assert cutset.config['a']==2
    assert cutset.tests[0].expected==['correct']
    assert cutset.tests[0].responses==['red']
    assert cutset.tests[0].url_name=="a_problem"

    abut2 = AnswerBoxUnitTest(dict(responses=["2"], expected="incorrect", url_name="x"))
    cutset.add_tests([abut2])
    assert len(cutset.tests)==2

def test_cutset2():
    yaml = """config: {a: 2}
tests:
- expected: [correct]
  name: A problem/test_1
  responses: [red]
  url_name: a_problem
    """
    cutset = CourseUnitTestSet(yaml_string=yaml)

    cfn = "/tmp/tmp_cutset.yaml"
    cutset.output_to_file(cfn)

    cutset2 = CourseUnitTestSet(cfn)
    assert len(cutset2.tests)==1
    assert cutset2.config['a']==2
    assert cutset2.tests[0].expected==['correct']
    assert cutset2.tests[0].responses==['red']
    assert cutset2.tests[0].url_name=="a_problem"


from pathlib import Path

import appdirs
from PySide6.QtCore import Signal

from mouse.classifier.cnn_classifier import PRETRAINED_MODELS_CHECKPOINTS
from mouseapp.model.utils import SerializableModel

class FilteringModel(SerializableModel):

    frequency_filter_changed = Signal(bool)
    frequency_threshold_changed = Signal(float)

    neural_network_filter_changed = Signal(bool)
    model_name_changed = Signal(str)
    model_batch_size_changed = Signal(int)
    model_confidence_threshold_changed = Signal(float)

    def __init__(self):
        super().__init__()

        self._default_values = {
            "_frequency_filter":
                False,
            "_frequency_threshold":
                18000.0,
            "_neural_network_filter":
                False,
            "_model_name":
                next(iter(PRETRAINED_MODELS_CHECKPOINTS)),
            "_batch_size":
                1,
            "_confidence_threshold":
                0.2,
            "_cache_dir":
                Path(appdirs.user_data_dir(appname="MoUSE")) /
                "nn_pretrained_models_cache",
        }
        # Frequency filtering
        self._frequency_filter: bool = False
        self._frequency_threshold: float = 0.0

        # Neural network filtering
        self._neural_network_filter: bool = False
        self._model_name = "cnn-binary-v1-custom"
        self._batch_size = 1
        self._confidence_threshold = 0.2
        self._cache_dir = None

        self.set_default_values()
        self.emit_all_setting_signals()

    def set_default_values(self):
        for key, val in self._default_values.items():
            setattr(self, key, val)

    @property
    def frequency_filter(self) -> bool:
        return self._frequency_filter

    @frequency_filter.setter
    def frequency_filter(self, value: bool):
        self._frequency_filter = value

    @property
    def frequency_threshold(self) -> float:
        return self._frequency_threshold

    @frequency_threshold.setter
    def frequency_threshold(self, value: float):
        self._frequency_threshold = value

    @property
    def neural_network_filter(self) -> bool:
        return self._neural_network_filter

    @neural_network_filter.setter
    def neural_network_filter(self, value: bool):
        self._neural_network_filter = value

    @property
    def model_name(self):
        return self._model_name

    @model_name.setter
    def model_name(self, value: str):
        if value not in PRETRAINED_MODELS_CHECKPOINTS:
            raise ValueError(f"Model type should be one of "
                             f"{list(PRETRAINED_MODELS_CHECKPOINTS.keys())} "
                             f"but found {value}")
        self._model_name = value

    @property
    def batch_size(self):
        return int(self._batch_size)

    @batch_size.setter
    def batch_size(self, value: int):
        if value <= 0:
            raise ValueError("Batch size should be greater than zero")
        self._batch_size = int(value)

    @property
    def confidence_threshold(self):
        return self._confidence_threshold

    @confidence_threshold.setter
    def confidence_threshold(self, value: float):
        if value < 0:
            raise ValueError("Confidence threshold should be in range [0, 1]")
        self._confidence_threshold = value

    @property
    def cache_dir(self):
        return self._cache_dir

    @cache_dir.setter
    def cache_dir(self, value: str):
        self._cache_dir = value

    def emit_all_setting_signals(self):
        self.frequency_filter_changed.emit(self.frequency_filter)
        self.frequency_threshold_changed.emit(self.frequency_threshold)

        self.neural_network_filter_changed.emit(self.neural_network_filter)
        self.model_name_changed.emit(self.model_name)
        self.model_batch_size_changed.emit(self.batch_size)
        self.model_confidence_threshold_changed.emit(self.confidence_threshold)

    def get_kwargs(self):
        kwargs = dict()
        for key in self._default_values.keys():
            value = getattr(self, key)
            kwargs[key[1:]] = value

        return kwargs

    def _value_to_dict(self, name, value):
        return value

    def _value_from_dict(self, name, value):
        return value


from flask import Flask, render_template, url_for, request
from mtranslate import translate
app = Flask(__name__)
@app.route('/')
def meteo():
    text = request.args.get('text')
    to_translate = text
    return translate(to_translate, 'fr')
if __name__ == "__main__":
    app.run()


import tifffile
from pathlib import Path
import matplotlib.pylab as plt
import numpy as np
import pandas as pd
from skimage.morphology import  remove_small_objects
from skimage.measure import label, regionprops

# https://pypi.org/project/hampel/
# https://dsp.stackexchange.com/questions/26552/what-is-a-hampel-filter-and-how-does-it-work
from hampel import hampel

import matplotlib as mpl
mpl.rcParams['figure.dpi'] = 300

# https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.RANSACRegressor.html#sklearn.linear_model.RANSACRegressor
from sklearn.linear_model import RANSACRegressor

#%%
########### helper functions

## calculate layer length 2nd method
# placenta image is vertical here, meaning edges are at the top and bottom
# layers increase left to right
def _find_bottom_layer_vertices(mask):
    list_layer_vertices = []
    n_rows, n_cols = mask.shape # subtracting cols length inverts graph
    for pos_row, row in enumerate(mask): # iterate through rows
        for pos_col, pixel_value in enumerate(row): #iterate through cols in row

            if pixel_value == True: # mask is at edge of mask
                list_layer_vertices.append((pos_row, n_cols-pos_col)) # save layer pixel
                break # go to next row

    return list_layer_vertices

## calculate layer length 2nd method
# placenta image is vertical here, meaning edges are at the top and bottom
# layers increase left to right
def _find_top_layer_vertices(mask):
    list_layer_vertices = []
    for pos_row, row in enumerate(mask): # iterate through rows
        for pos_col, pixel_value in enumerate(row): #iterate through cols in row

            if (pos_col+1) == len(row): # check if we've reached the end of the array
                break # goto next row

            if pixel_value == True: # mask edge found
                list_layer_vertices.append((pos_row, pos_col)) # save layer pixel
                break # go to next row
    return list_layer_vertices

def compute_layer_thickness(mask, method, debug=True):

    # validation
    if method not in [1,2]:
        print(f"Error invalid method id: {method}")
        return

    if debug:
        plt.title("input mask")
        plt.imshow(np.transpose(mask))
        plt.show()

    ############ remove small blobs (anything 10% or smaller)
    label_image, num_labels = label(mask, return_num=True)
    label_region_props = regionprops(label_image)
    for pos, region in enumerate(label_region_props):
        # print(f"pos: {pos} area: {region.area}")
        if pos == 0:   # initialize with first region
            largest_region = region  # initialize largest region
        elif region.area > largest_region.area:
            largest_region = region

    # remove
    layer_mask = label_image # this is done to supress warning about removing blobs on binary mask
    if num_labels > 2: # if num labels == 2 you only have bg and one connected component
        layer_mask = remove_small_objects(label_image, min_size=(largest_region.area*0.1))  # remove spots < 10% largest region found

    layer_mask[layer_mask > 0] = 1 # make mask binary of area will be off

    if debug:
        plt.title("after removing small blobs")
        plt.imshow(layer_mask)
        plt.show()

    ##### EDGE CALCULATION
    vertices_top = _find_top_layer_vertices(layer_mask)
    vertices_bottom = _find_bottom_layer_vertices(np.flip(layer_mask, axis=1))

    list_top_bottom_vertices = [vertices_top, vertices_bottom ]

    # show edges extracted
    # for vertices in list_top_bottom_vertices:
    #     list_vertex_rows = [rows for rows, _ in vertices] # extract height value
    #     list_vertex_heights = [cols for _, cols in vertices]

    #     # show vertices extracted
    #     plt.title("plot of vertices")
    #     plt.scatter(list_vertex_rows, list_vertex_heights, s=1)
    # plt.show()

    # Save equation coefficients, min and max
    list_coeffs = []

    for vertices in list_top_bottom_vertices:
        pass

        ##
        list_vertex_rows = [rows for rows, _ in vertices] # extract height value
        list_vertex_heights = [cols for _, cols in vertices]

        ###### apply hampel filter to remove outliers
        series_heights = pd.Series(list_vertex_heights)
        list_heights_cleaned = hampel(series_heights, window_size=11, n=1, imputation=True) # window size was 3

        # print(len(list_vertex_rows))
        # print(len(list_vertex_heights))
        # print(len(series_heights))
        # print(len(list_heights_cleaned))

        if debug:
            plt.title("red: original, black: after hampel filter")
            series_heights.plot(style="r-", alpha=1)
            series_heights_cleaned = pd.Series(list_heights_cleaned)
            series_heights_cleaned.plot(style="k-", alpha=1)
            plt.show()

        ####### Robtus Fitting RANSAC
        #https://stackoverflow.com/questions/55682156/iteratively-fitting-polynomial-curve/55787598

        from sklearn.metrics import mean_squared_error
        class PolynomialRegression(object):
            def __init__(self, degree=2, coeffs=None):
                self.degree = degree
                self.coeffs = coeffs

            def fit(self, X, y):
                self.coeffs = np.polyfit(X.ravel(), y, self.degree)

            def get_params(self, deep=False):
                return {'coeffs': self.coeffs}

            def set_params(self, coeffs=None, random_state=None):
                self.coeffs = coeffs

            def predict(self, X):
                poly_eqn = np.poly1d(self.coeffs)
                y_hat = poly_eqn(X.ravel())
                return y_hat

            def score(self, X, y):
                return mean_squared_error(y, self.predict(X))

        x_vals = np.asarray(list_vertex_rows)
        y_vals = np.asarray(list_heights_cleaned)

        if debug:
            plt.title("input to RANSACRegressor")
            plt.scatter(x_vals, y_vals, s=1)
            plt.show()

        poly_degree = 2
        stdevs = 3
        residual_threshold = stdevs * np.std(y_vals)
        ransac = RANSACRegressor(PolynomialRegression(degree=poly_degree),
                                  residual_threshold=residual_threshold,
                                  random_state=0)

        ransac.fit(np.expand_dims(x_vals, axis=1), y_vals)
        inlier_mask = ransac.inlier_mask_

        y_hat = ransac.predict(np.expand_dims(x_vals, axis=1))
        if debug:
            plt.plot(x_vals, y_vals, 'bx', label='input samples')
            plt.plot(x_vals[inlier_mask], y_vals[inlier_mask], 'go', markersize=2, label=f'inliers ({str(stdevs)}*STD)')
            plt.plot(x_vals, y_hat, 'r-', label='estimated curve')
            plt.legend()
            plt.show()

        list_vertex_rows

        coeffs = np.polyfit(x_vals, y_hat, poly_degree)
        list_coeffs.append([coeffs, (np.min(list_vertex_rows), np.max(list_vertex_rows))])

    mask = np.transpose(mask) # compute things on a horizontal mask
    n_rows, n_cols = mask.shape
    # plt.imshow(mask)
    # plt.show()

    # METHOD 1 - CALCULATE MIDDLE LINE
    if method == 1:
        #print("method 1 selected")
        poly_top_edge = np.poly1d(list_coeffs[0][0])
        poly_bottom_edge = np.poly1d(list_coeffs[1][0])

        x_vals = np.linspace(0, n_cols, num=(n_cols +1)) # +1 to produce whole numbers/pixels

        y_hat_top = poly_top_edge(x_vals) # top is lower number due to origin on top left
        y_hat_bottom = poly_bottom_edge(x_vals)

        y_hat_middle = y_hat_top + ((y_hat_bottom - y_hat_top)/2)

        # Fit new line and get y values
        coeffs_middle_poly = np.polyfit(x_vals, y_hat_middle, poly_degree)
        poly_middle = np.poly1d(coeffs_middle_poly)
        y_hat_middle = poly_middle(x_vals)

        # Only keep pixels in image
        bool_array_valid_points = y_hat_middle <= n_rows
        x_vals_within_image = x_vals[bool_array_valid_points]
        y_vals_within_image = y_hat_middle[bool_array_valid_points]

        length = 0
        for pos, (x,y) in enumerate(zip(x_vals_within_image, y_vals_within_image)):
            pass
            # reached last value
            index_next_point = idx_curr_value =  pos+1
            if index_next_point == len(x_vals_within_image):
                break

            x_dist = np.absolute(x-x_vals_within_image[index_next_point])
            y_dist = np.absolute(y-y_vals_within_image[index_next_point])
            length +=np.sqrt(x_dist**2 + y_dist**2) # pythagoras

        thickness = np.sum(mask)/length

        if debug:
            plt.title(f"method 1 center line\n layer length: {length:.4f} \n thickness: {thickness:.4f}")
            plt.imshow(mask)
            plt.plot(x_vals_within_image, y_vals_within_image, '-',  linewidth=1)
            plt.show()

        return thickness, [coeffs_middle_poly]

    if method == 2:
        #print("method 2 selected")
        # METHOD 2 - CALCULATE TOP AND BOTTOM EDGES AND AVERAGE DISTANCE

        list_layer_lengths = []

        if debug:
            plt.imshow(mask)

        # Average top and bottom lengths
        list_points_edges = []
        for equation_params in list_coeffs:
            pass
            coeffs, (min_value,max_value) = equation_params
            poly_eqn = np.poly1d(coeffs)

            # y values part of the image
            x_vals = np.linspace(0, n_cols, num=(n_cols +1)) # +1 to produce whole numbers/pixels
            y_hat = poly_eqn(x_vals)

            # Only keep pixels in image
            bool_array_valid_points = y_hat <= n_rows
            x_vals_within_image = x_vals[bool_array_valid_points]
            y_vals_within_image = y_hat[bool_array_valid_points]

            # store points in list_to_return
            list_points_edges.append((x_vals_within_image,y_vals_within_image))

            # Calculate top and bottom lengths
            length = 0
            for pos, (x, y) in enumerate(zip(*[x_vals_within_image, y_vals_within_image])) :
                pass
                index_next_point = idx_curr_value =  pos+1

                #last value outside of array, no next point
                if idx_curr_value == len(x_vals_within_image):
                    break
                # calculate distance
                x_dist = np.absolute(x-x_vals_within_image[index_next_point])
                y_dist = np.absolute(y-y_vals_within_image[index_next_point])
                length +=np.sqrt(x_dist**2 + y_dist**2) # pythagoras
            list_layer_lengths.append(length)

            #plot image
            if debug:
                plt.plot(x_vals_within_image, y_vals_within_image, '-', label='estimated curve', linewidth=1)

        #calculate mean and finally plot lines
        mean_length = np.mean(list_layer_lengths)
        area = np.sum(mask)
        thickness = area/mean_length

        if debug:
            plt.title(f"method 2 avg top and bottom \n top layer: {list_layer_lengths[0]:.4f} bottom layer: {list_layer_lengths[1]:.4f} mean: {mean_length:.4f} \n thickness: {thickness:.4f} ")
            plt.show()

        # return thickness and coeffs of polynomials
        return thickness, mean_length, area, [list_coeffs[0][0], list_coeffs[1][0]] , list_points_edges

#%%

if __name__ == "__main__":
    pass

# Algorithm --> Smooth curved surfaces
# for each mask -->
# to find the top and bottom
# 	for each column find top and bottom masks and take average

working_dir = Path("C:/Users/Nabiki/Desktop/split_masks_selected")
im_paths = list(working_dir.glob("*.tiff"))

#iterate through every mask
for im_path in im_paths: #[3:4]:
    pass
        # LOAD AND SHOW MASK
    mask = tifffile.imread(im_path)
    mask = mask.transpose() ################## image must be vertical and binary
    # plt.title("initial working image")
    # plt.imshow(mask)
    # plt.show()
    method = 2
    thickness = compute_layer_thickness(mask, method, show_images=False)


import pandas as pd
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
from scipy.stats import linregress

def filtered_signal(S,cutoff_frequency,sampling_frequency,order):
    # Define the Butterworth high-pass filter
    b, a = signal.butter(order, cutoff_frequency / (0.5 * sampling_frequency), btype='high')

    # Apply the high-pass filter to the accelerometer signal
    filtered_S_signal = signal.filtfilt(b, a, S)
    return filtered_S_signal

def Speed_Dependency(cutoff_frequency,sampling_frequency,order,S,Yacc):
    filtered_S_signal=filtered_signal(S,cutoff_frequency,sampling_frequency,order)
    # Calculate the moving average filter E with a rolling window
    rolling_window_size = 2000

    filtered_Yacc=filtered_signal(Yacc,30,400,4)
    filtered_Yacc_series_ = pd.Series(filtered_Yacc)
    # Calculate H ° S(t) and E ° |H| ° Yacc(t)
    E=np.abs(filtered_Yacc_series_).rolling(window=rolling_window_size, min_periods=1, center=False).mean()

    H_composed =filtered_S_signal   # H ° S(t)
    E_composed = E  # E ° |H| ° Yacc(t)

    dS= H_composed / E_composed
    return dS

from scipy.stats import linregress

def Speed_Linear_Regression(Velocity,Acceleration):
    # Perform linear regression
    slope, intercept, r_value, p_value, std_err = linregress(Velocity, Acceleration)

    # Calculate residuals
    predicted_vertical_acceleration = slope * Velocity + intercept
    residuals = Acceleration - predicted_vertical_acceleration
    return residuals


__author__ = "Charles Zhang"
__time__ = "2020-06-05 11:02"

import gym

# random CartPole agent
if __name__ == "__main__":
    env = gym.make("CartPole-v0")

    total_reward = 0.0
    total_steps = 0
    obs = env.reset()       # four number: x coordinate of center,  speed, angle to platform, angular speed

    while True:
        action = env.action_space.sample()      # random sample from underlying space(0 for left, 1 for right)
        obs, reward, done, _ = env.step(action)
        total_reward += reward
        total_steps += 1
        if done:
            break

    print("Episode done in %d steps, total reward %.2f" % (
        total_steps, total_reward))


import os

from setuptools import find_packages, setup

cwd = os.path.dirname(os.path.realpath(__file__))
file = os.path.join(cwd, 'requirements.txt')
with open(file) as f:
    dependencies = list(map(lambda x: x.replace("\n", " "), f.readlines()))

setup(
    name='hand-crafted-models',
    version='1.0',
    description='Hand-crafted discriminative linear predictive models',
    author='Samuel Luo',
    author_email='viridis959@gmail.com',
    url='https://github.com/viridis959',
    install_requires=dependencies,
    packages=find_packages(),
)


import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

X1 = [2, 2, -2, -2, 1, 1, -1, -1]
X2 = [2, -2, -2, 2, 1, -1, -1, 1]

Y = [1, 1, 1, 1, 2, 2, 2, 2]

alldata = pd.DataFrame({"X1": X1, "X2": X2, "Y": Y})
X = alldata.loc[:, ["X1", "X2"]]
y = alldata.Y

plt.scatter(X[(y == 1)].X1, X[(y==1)].X2, c="red", marker="+")
plt.scatter(X[(y == 2)].X1, X[(y==2)].X2, c="blue", marker="o")
# plt.show()

x1 = np.arange(min(X.X1.tolist()), max(X.X1.tolist()), 0.01)
x2 = np.arange(min(X.X2.tolist()), max(X.X2.tolist()), 0.01)
xx, yy = np.meshgrid(x1, x2)

from sklearn import svm
from sklearn.metrics import accuracy_score
clf = svm.SVC(kernel="rbf", gamma=1)
clf = clf.fit(X, y)
pred = clf.predict(np.c_[xx.ravel(), yy.ravel()])
pred = pred.reshape(xx.shape)
plt.contour(xx, yy, pred, colors="cyan")
# plt.show()

clf = svm.SVC(kernel="rbf", gamma=1)
clf = clf.fit(X, y)
pred = clf.predict(X)
print(accuracy_score(y, pred))

clf = svm.SVC(kernel="rbf", gamma=1000000)
clf = clf.fit(X, y)
pred = clf.predict([[-2.0, -1.9]])
print(pred)
pred = clf.predict(np.c_[xx.ravel(), yy.ravel()])
pred = pred.reshape(xx.shape)
plt.contour(xx, yy, pred, colors="purple")
plt.show()


import json
import sqlite3
from collections import defaultdict, Counter
from random import choice
from flask import Flask, request, jsonify, make_response, redirect

def get_relation(block):
    prefix = '# relation = '
    for line in block.splitlines():
        if line.startswith(prefix):
            return line.strip()[len(prefix):]

def populate_headers_basic(resp):
    resp.headers['Access-Control-Allow-Origin'] = '*'
    resp.headers['Access-Control-Allow-Credentials'] = 'true'

def populate_headers_json(resp):
    populate_headers_basic(resp)
    resp.headers['Content-Type'] = 'application/json'

def populate_headers_text(resp):
    populate_headers_basic(resp)
    resp.headers['Content-Type'] = 'text/plain'

def get_processed():
    with open('data/processed.json', 'r', encoding='utf-8') as inp:
        return {k: set(v) for k, v in json.load(inp).items()}

def dump_processed(processed_dict):
    with open('data/processed.json', 'w', encoding='utf-8') as out:
        json.dump({k: sorted(v) for k, v in processed_dict.items()}, out, indent=2)

def get_discarded():
    with open('data/discarded.json', 'r', encoding='utf-8') as inp:
        return set(json.load(inp))

def dump_discarded(discarded_set):
    with open('data/discarded.json', 'w', encoding='utf-8') as out:
        json.dump(sorted(discarded_set), out, indent=2)

app = Flask(__name__)

dbconn = sqlite3.connect('data/tacred_align.sqlite')
cursor = dbconn.cursor()

record_dict = {
    record_id : {
        'en': en,
        'ru_original': ru,
        'ru_modified': ru_mod,
        'ko_original': ko,
        'ko_modified': ko_mod
    }
    for record_id, en, ru, ru_mod, ko, ko_mod
    in cursor.execute("SELECT * FROM align")
}
record_ids = [el for el in record_dict]

relation_dict = {
    record_id : get_relation(blocks['en'])
    for record_id, blocks in record_dict.items()
}

with open('requirements.json', 'r', encoding='utf-8') as inp:
    requirements = json.load(inp)

def needed(record_id, language, processed, discarded):
    # Try discarding by id
    if record_id in processed['both'] or \
        record_id in processed[language] or \
        record_id in discarded:
        return False
    # Try discarding by relation
    relation = relation_dict[record_id]
    satisfied = get_satisfied(processed)
    if requirements[relation] == satisfied["both"][relation] or \
        requirements[relation] == satisfied[language][relation]:
        return False
    return True

def get_satisfied(processed):
    result = {
        'ko': { k: 0 for k in requirements },
        'ru': { k: 0 for k in requirements },
        'both': { k: 0 for k in requirements }
    }
    for key in ['ru', 'ko', 'both']:
        for record_id in processed[key]:
            relation = relation_dict[record_id]
            result[key][relation] += 1
    return result

@app.route('/stats', methods=['GET'])
def stats_handler():
    processed = get_processed()
    satisfied = get_satisfied(processed)
    relations = sorted(requirements, key=lambda rel: requirements[rel], reverse=True)
    buffer = []
    buffer.append('total')
    buffer.append(f'\tru: {sum(satisfied["ru"].values()) + sum(satisfied["both"].values())}')
    buffer.append(f'\tko: {sum(satisfied["ko"].values()) + sum(satisfied["both"].values())}')
    buffer.append(f'out of {sum(requirements.values())}\n')
    for rel in relations:
        buffer.append(rel)
        buffer.append(f'\tru: {satisfied["ru"][rel] + satisfied["both"][rel]}')
        buffer.append(f'\tko: {satisfied["ko"][rel] + satisfied["both"][rel]}')
        buffer.append(f'out of {requirements[rel]}\n')
    resp = make_response('\n'.join(buffer), 200)
    populate_headers_text(resp)
    return resp

@app.route('/<language>/byid/<record_id>', methods=['GET'])
def byid_handler(language, record_id):
    if language not in ['ru', 'ko']:
        response = make_response(f'Wrong language: {language}', 400)
        response.headers['Content-Type'] = 'text/plain'
        response.headers['Access-Control-Allow-Origin'] = '*'
        return response
    elif record_id not in record_dict:
        response = make_response(f'Wrong id: {record_id}', 400)
        response.headers['Content-Type'] = 'text/plain'
        response.headers['Access-Control-Allow-Origin'] = '*'
        return response

    # TODO: notify if a discarded record is requested
    processed = get_processed()
    done_in_other_lang = False
    other_lang = 'ru' if language == 'ko' else 'ko'
    if record_id in processed[other_lang]:
        done_in_other_lang = True
    response = make_response(jsonify({
        'id': record_id,
        'done_in_other_lang': done_in_other_lang,
        'source': record_dict[record_id]['en'],
        'target': record_dict[record_id]['ru_modified' if language == 'ru' else 'ko_modified']
    }), 200)
    populate_headers_json(response)
    return response

@app.route('/<language>/nextsentence', methods=['GET'])
def nextsentence_handler(language):
    if language not in ['ru', 'ko']:
        response = make_response(f'Wrong language: {language}', 400)
        response.headers['Content-Type'] = 'text/plain'
        response.headers['Access-Control-Allow-Origin'] = '*'
        return response
    discarded = get_discarded()
    processed = get_processed()

    done_in_other_lang = False
    # First try to suggest sentences already aligned by the other fella.
    other_lang = 'ru' if language == 'ko' else 'ko'
    if processed[other_lang]:
        next_id = processed[other_lang].pop()
        processed[other_lang].add(next_id)  # Delete only when the sentence is returned.
        done_in_other_lang = True
    # If this fails, suggest a random sentence.
    # Will enter an infinite loop when all TACRED sample is processed!
    else:
        while True:
            next_id = choice(record_ids)
            if requirements == get_satisfied(processed):
                # Any non-processed and non-discarded sentence will do.
                if next_id in processed['both'] or \
                    next_id in processed[language] or \
                    next_id in discarded:
                    continue
                else:
                    break
            if needed(next_id, language, processed, discarded):
                # Sample unfinished relations.
                break

    response = make_response(jsonify({
        'id': next_id,
        'done_in_other_lang': done_in_other_lang,  # So that people do not discard lightly.
        'source': record_dict[next_id]['en'],
        'target': record_dict[next_id]['ru_modified' if language == 'ru' else 'ko_modified']
    }), 200)
    populate_headers_json(response)
    return response

@app.route('/<language>/discardsentence', methods=['POST'])
def discard_sentence_handler(language):
    if language not in ['ru', 'ko']:
        response = make_response(f'Wrong language: {language}', 400)
        populate_headers_text(response)
        return response
    data = json.loads(request.data)
    discarded = get_discarded()
    processed = get_processed()
    discarded.add(data['id'])
    for k in processed:
        processed[k].discard(data['id'])
    dump_discarded(discarded)
    dump_processed(processed)
    response = make_response('Update successful', 200)
    populate_headers_text(response)
    return response

@app.route('/<language>/updatesentence', methods=['POST'])
def update_sentence_handler(language):
    if language not in ['ru', 'ko']:
        response = make_response(f'Wrong language: {language}', 400)
        populate_headers_text(response)
        return response

    data = json.loads(request.data)
    processed = get_processed()
    record_id = data['id']
    target_block = data['conllu']

    # Update in the dict
    record_dict[record_id]['ru_modified' if language == 'ru' else 'ko_modified'] = target_block

    # Update in the db
    cursor.execute(
        f"""
        UPDATE align SET `{"ru_modified" if language == "ru" else "ko_modified"}` = ?
        WHERE `id` = ?""",
        (target_block, record_id))
    dbconn.commit()

    # Update stats
    other_lang = 'ru' if language == 'ko' else 'ko'
    if record_id in processed[other_lang]:
        processed['both'].add(record_id)
        processed[other_lang].remove(record_id)
    else:
        processed[language].add(record_id)
    dump_processed(processed)

    response = make_response('Update successful', 200)
    populate_headers_text(response)
    return response


"""
deep copy of the graph

initialize a dictionary to pair old node with new one
traversal the tree BFS
1. create queue with [initial root nodes]
2. while loop when queue not empty:
    popleft queue get the cur node
    for neighbour in this old node
        if node not in dic:
            create new node and pair it with old one in dic
            queue append this old node
        new node(pair with old node) append this new children

3. return root

create new nodes on the go
"""

"""
# Definition for a Node.
"""
class Node:
    def __init__(self, val = 0, neighbors = None):
        self.val = val
        self.neighbors = neighbors if neighbors is not None else []
    def __str__(self):
        print(self.val, self.neighbours)

from collections import deque
class Solution:

    def __init__(self):
        self.visited = {}
    def copyDFS(self, node: Node):
        if not node: return node

        # Create a clone for the given node.
        # Note that we don't have cloned neighbors as of now, hence [].
        newnode = Node(node.val, [])
        # The key is original node and value being the clone node.
        self.visited[node] = newnode

        # Iterate through the neighbors to generate their clones
        # and prepare a list of cloned neighbors to be added to the cloned node.
        for neighbor in node.neighbors:
            # If the node was already visited before.
            # Return the clone from the visited dictionary.

            if neighbor not in self.visited:
                self.cloneGraph(neighbor)
            newnode.neighbors.append(self.visited[neighbor])
        return newnode

    def copyGraph(self, node: Node):
        if not node: return node
        root = Node(node.val, [])
        queue = deque()
        # queue will append nodes -- root nodes may not be only one
        queue.append(node)
        # pair each node with a new node(one child has multiple parents)
        dictionary = {node: root}
        # BFS traversal
        while queue:
            item = queue.popleft()
            for neighbour in item.neighbors:
                if neighbour not in dictionary:
                    newnode = Node(neighbour.val, [])
                    dictionary[neighbour] = newnode

                    queue.append(neighbour)

                dictionary[item].neighbors.append(dictionary[neighbour])
        return root

node = Node(2, [Node(3, []), Node(4, []), Node(5, [Node(1, [])])])

Solution().copyGraph(node)


#!/usr/bin/env python
import argparse, random

parser = argparse.ArgumentParser()
parser.add_argument("-n", type=int, help="number of words to print, default=6", default=6)
args = parser.parse_args()

r = random.SystemRandom()
with open('eff_large_wordlist.txt') as f:
    lines = list(f)
    print(' '.join(r.choice(lines).split()[1] for i in range(args.n)))


"""
__author__ = "Hager Rady and Mo'men AbdelRazek"

Main
-Capture the config file
-Process the json config passed
-Create an agent instance
-Run the agent
"""

import argparse
from utils.config import *

from agents import *

def main():
    # parse the path of the json config file
    arg_parser = argparse.ArgumentParser(description="")
    arg_parser.add_argument(
        'config',
        metavar='config_json_file',
        default='None',
        help='The Configuration file in json format')
    args = arg_parser.parse_args()

    # parse the config json file
    config = process_config(args.config)

    # Create the Agent and pass all the configuration to it then run it..
    agent_class = globals()[config.agent]
    agent = agent_class(config)
    agent.run()
    agent.finalize()

if __name__ == '__main__':
    main()


from flask import Flask, request, jsonify
import datetime
import os

app = Flask(__name__)

# Global variable to store the start time
start_time = None

def get_start_time():
    global start_time
    if start_time is None:
        # Check if the start time is stored in a file or a database
        # If the file doesn't exist or database is empty, set the start time to the current time
        # For simplicity, I'll just set the start time to the current time
        start_time = datetime.datetime.now()
    return start_time

@app.route('/api/welcome', methods=['POST'])
def welcome_python_app():
    data = request.json
    user_input = data.get('user_input', '').lower()

    if user_input == 'hello':
        current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        reply = f'Welcome to the Python app! The app is active from last {calculate_time_since_start()}'
        return jsonify({'reply': reply})
    else:
        return jsonify({'reply': 'Unknown input'})

def calculate_time_since_start():
    current_time = datetime.datetime.now()
    duration = current_time - get_start_time()
    total_seconds = int(duration.total_seconds())

    minutes, seconds = divmod(total_seconds, 60)
    hours, minutes = divmod(minutes, 60)

    if hours > 0 and minutes > 0:
        return f'{hours} hours and {minutes} minutes.'
    elif hours > 0:
        return f'{hours} hours.'
    elif minutes > 0:
        return f'{minutes} minutes.'
    else:
        return 'less than a minute.'

@app.route('/', methods=['POST'])
def welcome_react_app():
    data = request.json
    user_input = data.get('user_input', '').lower()

    if user_input == 'hello':
        current_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        reply = f'Welcome to the React app! The app is active from last {calculate_time_since_start()}'
        return jsonify({'reply': reply})
    else:
        return jsonify({'reply': 'Unknown input'})

if __name__ == '__main__':
    # On application start, get the start time
    start_time = get_start_time()
    app.run()


from django.shortcuts import render, redirect
from . models import *
from .forms import PostForm
# Create your views here.

def index(request):
    all_posts = Post.objects.all()
    context = {
        'all_posts':all_posts
    }
    return render(request, 'pages/index.html', context)

def createPost(request):
    form = PostForm()
    if request.method == 'POST':
        form = PostForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            return redirect('indexPage')
    context = {
        'form':form,
        }
    return render(request, 'post/create.html', context)

def detailPost(request, pk):
    post = Post.objects.get(id=pk)
    form = PostForm()
    context = {
        'post':post,
        'form':form
    }
    return render(request, 'post/detail.html', context )