class MatplotlibWidgetWFPot(QtGui.QGraphicsView):

    def __init__(self, parent = None):
        QtGui.QWidget.__init__(self, parent)
        self.canvas = MplCanvas()
        self.vbl = QtGui.QVBoxLayout()
        self.vbl.addWidget(self.canvas)
        self.setLayout(self.vbl)
        self.canvas.ax.set_title('Calculated PCB electrode potentials', fontsize=10)
        self.canvas.fig.patch.set_alpha(0)
        self.mpl_toolbar = NavigationToolbar(self.canvas, self)
        params = {
                  'legend.fontsize': 8,
                  'xtick.labelsize': 8,
                  'ytick.labelsize': 8,
                  'legend.handletextpad': .5,
                }
        plt.rcParams.update(params)
        self.mpl_toolbar.pan()

        
    def plot(self, wfPotentials, plotitems):
        if hasattr(wfPotentials, 'plotTime'):
            argX = wfPotentials.plotTime
            argY = wfPotentials.potentialsOut
            # get axis limits to not reset zoom/pan
            axlim = self.canvas.ax.axis()
            self.canvas.ax.clear()
            if not any(plotitems):
                self.canvas.draw()
                return
            if plotitems[0]:
                self.canvas.ax.plot(argX, argY[1,:], 'r.')
                self.canvas.ax.plot(argX, argY[1,:], 'r', label="2", linewidth=1.2)
            if plotitems[1]:
                self.canvas.ax.plot(argX, argY[3,:], 'b.')
                self.canvas.ax.plot(argX, argY[3,:], 'b', label="4", linewidth=1.2)
            if plotitems[2]:
                self.canvas.ax.plot(argX, argY[5,:], 'g.')
                self.canvas.ax.plot(argX, argY[5,:], 'g', label="6", linewidth=1.2)
            if not axlim == (0.0, 1.0, 0.0, 1.0):
                self.canvas.ax.axis(axlim)
            else: pass
            self.canvas.ax.grid(True)
            self.canvas.ax.set_title("Calculated PCB electrode potentials", fontsize=10)
            self.canvas.ax.set_xlabel("Time ($\mu$s)", fontsize=10)
            self.canvas.ax.set_ylabel("Amplitude (bits)", fontsize=10)
            self.canvas.ax.legend(bbox_to_anchor=(0.02, 0.99), loc=2, borderpad=None, borderaxespad=0., fontsize=8, frameon=False)
            # mares in potential generation 
            self.canvas.ax.plot([wfPotentials.incplTime,wfPotentials.incplTime],[(wfPotentials.maxAmp*2+50),-50], 'k--', linewidth=1.5)
            self.canvas.ax.plot([wfPotentials.plotTime[-1]-wfPotentials.outcplTime, wfPotentials.plotTime[-1]-wfPotentials.outcplTime], \
            [-1,wfPotentials.maxAmp*2+1], 'k--', linewidth=1.5)
            #self.WaveformDisplay.canvas.ax.plot([wfPotentials.incplTime+wfPotentials.decelTime,\
            #wfPotentials.incplTime+wfPotentials.decelTime],[wfPotentials.maxAmp*-2-1, wfPotentials.maxAmp*2+1], 'k--', linewidth=1)
            self.canvas.fig.patch.set_alpha(0)
            self.canvas.fig.tight_layout()
            self.canvas.draw()
        else:
            print 'No potentials generated'
Esempio n. 2
0
class Window(QtGui.QDialog):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure)

        self.toolbar = NavigationToolbar(self.canvas, self)
        self.toolbar.hide()

        # Just some button
        self.button = QtGui.QPushButton('Plot')
        self.button.clicked.connect(self.plot)

        self.button1 = QtGui.QPushButton('Zoom')
        self.button1.clicked.connect(self.zoom)

        self.button2 = QtGui.QPushButton('Pan')
        self.button2.clicked.connect(self.pan)

        self.button3 = QtGui.QPushButton('Home')
        self.button3.clicked.connect(self.home)

        # set the layout
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)
        layout.addWidget(self.button)
        layout.addWidget(self.button1)
        layout.addWidget(self.button2)
        layout.addWidget(self.button3)
        self.setLayout(layout)

    def home(self):
        self.toolbar.home()

    def zoom(self):
        self.toolbar.zoom()

    def pan(self):
        self.toolbar.pan()

    def plot(self):
        ''' plot some random stuff '''
        data = [random.random() for i in range(25)]
        ax = self.figure.add_subplot(111)
        ax.hold(False)
        ax.plot(data, '*-')
        self.canvas.draw()
Esempio n. 3
0
    def pan(self, *args):
        """

        :param args:
        :return:
        """
        NavigationToolbar2.pan(self, args)

        if self._navigationMode == MyNavigationToolbar.NAVIGATION_MODE_PAN:
            # out of pan mode
            self._navigationMode = MyNavigationToolbar.NAVIGATION_MODE_NONE
        else:
            # into pan mode
            self._navigationMode = MyNavigationToolbar.NAVIGATION_MODE_PAN

        return
Esempio n. 4
0
    def pan(self, *args):
        """

        :param args:
        :return:
        """
        NavigationToolbar2.pan(self, args)

        if self._navigationMode == MyNavigationToolbar.NAVIGATION_MODE_PAN:
            # out of pan mode
            self._navigationMode = MyNavigationToolbar.NAVIGATION_MODE_NONE
        else:
            # into pan mode
            self._navigationMode = MyNavigationToolbar.NAVIGATION_MODE_PAN

        return
Esempio n. 5
0
class PlotManager(QtGui.QWidget):
    def __init__(self, parent=None):
        super(PlotManager, self).__init__(parent)
        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure)
        self.toolbar = NavigationToolbar(self.canvas, self)
        self.toolbar.hide()
        self.zoombut = QtGui.QPushButton("Збільшити")
        self.zoombut.clicked.connect(self.zoom)
        self.panbut = QtGui.QPushButton("Перемістити")
        self.panbut.clicked.connect(self.pan)
        self.homebut = QtGui.QPushButton("Повністю")
        self.homebut.clicked.connect(self.home)
        self.savebut = QtGui.QPushButton("Зберегти")
        self.savebut.clicked.connect(self.save)
        layout = QtGui.QVBoxLayout()
        buttonbox = QtGui.QHBoxLayout()
        buttonbox.addWidget(self.zoombut)
        buttonbox.addWidget(self.panbut)
        buttonbox.addWidget(self.homebut)
        buttonbox.addWidget(self.savebut)
        layout.addLayout(buttonbox)
        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)
        self.setLayout(layout)
        self.ax = self.figure.add_subplot(111)

    def home(self):
        self.toolbar.home()

    def zoom(self):
        self.toolbar.zoom()

    def pan(self):
        self.toolbar.pan()

    def save(self):
        timestr = time.strftime("%Y%m%d_%H%M%S", time.gmtime())
        self.figure.savefig(f'{timestr}.png')
Esempio n. 6
0
 def pan(self):
     NavigationToolbar.pan(self)
     self.mode = ""  #<--- whatever you want to replace "pan/zoom" goes here
     self.set_message(self.mode)
Esempio n. 7
0
class PyWeramiWindow(QtGui.QMainWindow, Ui_MainWindow):

    def __init__(self, filename=None, parent=None):
        super(PyWeramiWindow,self).__init__(parent)
        self.settings = QtCore.QSettings("LX", "pywerami")
        self.setupUi(self)
        self._fig = plt.figure(facecolor="white")
        self._ax = self._fig.add_subplot(111)

        self._canvas = FigureCanvas(self._fig)
        self._canvas.setParent(self.widget)
        self._canvas.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.matplot.addWidget(self._canvas)
        self.mpl_toolbar = NavigationToolbar(self._canvas,self.widget)
        self.mpl_toolbar.hide()
        self.matplot.addWidget(self.mpl_toolbar)

        #set combos
        self.cmaps = [m for m in plt.cm.datad if not m.endswith("_r")]
        self.mapstyle.addItems(self.cmaps)

        # set validators
        self.levelmin.setValidator(QtGui.QDoubleValidator(self.levelmin))
        self.levelmax.setValidator(QtGui.QDoubleValidator(self.levelmax))
        self.levelnum.setValidator(QtGui.QIntValidator(self.levelmin))
        self.levelstep.setValidator(QtGui.QDoubleValidator(self.levelstep))
        self.clipmin.setValidator(QtGui.QDoubleValidator(self.clipmin))
        self.clipmax.setValidator(QtGui.QDoubleValidator(self.clipmax))
        
        # Set icons in toolbar
        self.actionOpen.setIcon(QtGui.QIcon.fromTheme('document-open'))
        self.actionSave.setIcon(QtGui.QIcon.fromTheme('document-save'))
        self.actionSaveas.setIcon(QtGui.QIcon.fromTheme('document-save-as'))
        self.actionImport.setIcon(QtGui.QIcon.fromTheme('x-office-spreadsheet'))
        self.actionHome.setIcon(self.mpl_toolbar._icon('home.png'))
        self.actionPan.setIcon(self.mpl_toolbar._icon('move.png'))
        self.actionZoom.setIcon(self.mpl_toolbar._icon('zoom_to_rect.png'))
        self.actionGrid.setIcon(QtGui.QIcon.fromTheme('format-justify-fill'))
        self.actionAxes.setIcon(self.mpl_toolbar._icon('qt4_editor_options.png'))
        self.actionSavefig.setIcon(self.mpl_toolbar._icon('filesave.png'))
        #self.action3D.setIcon(QtGui.QIcon.fromTheme(''))
        self.actionProperties.setIcon(QtGui.QIcon.fromTheme('preferences-other'))
        self.actionQuit.setIcon(QtGui.QIcon.fromTheme('application-exit'))
        self.actionAbout.setIcon(QtGui.QIcon.fromTheme('help-about'))
        
        self.actionImport.triggered.connect(self.import_data)
        self.actionHome.triggered.connect(self.mpl_toolbar.home)
        self.actionPan.triggered.connect(self.plotpan)
        self.actionZoom.triggered.connect(self.plotzoom)
        self.actionGrid.triggered.connect(self.plotgrid)
        self.actionAxes.triggered.connect(self.mpl_toolbar.edit_parameters)
        self.actionSavefig.triggered.connect(self.mpl_toolbar.save_figure)
        self.actionProperties.triggered.connect(self.edit_options)
        self.actionQuit.triggered.connect(self.close)
        if filename:
            self.import_data(filename)
        
        # ready
        self.statusbar.showMessage("Ready", 5000)

    def closeEvent(self,event):
        reply=QtGui.QMessageBox.question(self,'Message',"Are you sure to quit?",QtGui.QMessageBox.Yes,QtGui.QMessageBox.No)
        if reply==QtGui.QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()

    def import_data(self, filename=None):
        if not filename:
            filename = QtGui.QFileDialog.getOpenFileName(self, "Import tab file", ".", "TAB (*.tab);;All files (*.*)")
        if filename:
            self.data = WeramiData.from_tab(filename)

            # populate listview and setup properties
            self.props = {}
            self._model = QtGui.QStandardItemModel(self.listView)
            for var in self.data.dep:
                item = QtGui.QStandardItem(var)
                item.setCheckable(True)
                self._model.appendRow(item)
                self.default_var_props(var)

            self.listView.setModel(self._model)
            self.listView.show()
            # connect listview signals
            self.varSel = self.listView.selectionModel()
            self.varSel.selectionChanged.connect(self.on_var_changed)
            self._model.itemChanged.connect(self.plot)
            # buttons signals
            self.buttonBox.button(QtGui.QDialogButtonBox.Apply).clicked.connect(self.apply_props)
            self.buttonBox.button(QtGui.QDialogButtonBox.RestoreDefaults).clicked.connect(self.restore_props)
            self.contcolor.clicked.connect(self.contours_color)
            self.action3D.triggered.connect(self.switch3d)
            # signals to calculate step size
            self.levelmin.editingFinished.connect(self.step_from_levels)
            self.levelmax.editingFinished.connect(self.step_from_levels)
            self.levelnum.editingFinished.connect(self.step_from_levels)
            self.setlevels.toggled.connect(self.step_from_levels)
            
            # all done focus
            self.action3D.setChecked(False) # no 3d on import
            self.varSel.setCurrentIndex(self._model.index(0, 0), QtGui.QItemSelectionModel.ClearAndSelect | QtGui.QItemSelectionModel.Rows)
            self.listView.setFocus()
            self.plot()
            self.statusbar.showMessage("Data from {} imported".format(self.data.label), 5000)

    def contours_color(self):
    	col = QtGui.QColorDialog.getColor()
    	if col.isValid():
            self.contcolor.setStyleSheet("background-color: {}".format(col.name()))

    def step_from_levels(self):
        if self.setlevels.isChecked():
            step = (float(self.levelmax.text()) - float(self.levelmin.text())) / (int(self.levelnum.text()) - 1)
            self.levelstep.setText(repr(step))
            self.props[self.var]['step'] = step

    def default_var_props(self, var):
        data = self.data.get_var(var)
        prop = {}
        #levels
        prop['min'] = data.min()
        prop['max'] = data.max()
        prop['num'] = 10
        prop['step'] = (prop['max'] - prop['min']) / (prop['num'] - 1)
        prop['levels'] = 'num'
        prop['type'] = 'linear'
        #style
        prop['fill'] = False
        prop['opacity'] = 100
        prop['cmap'] = 'jet'
        prop['contours'] = 'color'
        prop['color'] = '#000000'
        prop['label'] = False
        #processing
        prop['resample'] = 1
        prop['median'] = 1
        prop['gauss'] = 0
        prop['clipmin'] = data.min()
        prop['clipmax'] = data.max()

        self.props[var] = prop

    def set_var_props(self, var):
        #levels
        self.levelmin.setText(repr(self.props[var]['min']))
        self.levelmax.setText(repr(self.props[var]['max']))
        self.levelnum.setText(repr(self.props[var]['num']))
        self.levelstep.setText(repr(self.props[var]['step']))
        if self.props[var]['levels'] == 'num':
            self.setlevels.setChecked(True)
        else:
            self.setstep.setChecked(True)
        if self.props[var]['type'] == 'linear':
            self.linlevel.setChecked(True)
        else:
            self.cdflevel.setChecked(True)
        #style
        if self.props[var]['fill']:
            self.fillstyle.setChecked(True)
        else:
            self.fillstyle.setChecked(False)
        self.opacity.setValue(self.props[var]['opacity'])
        self.mapstyle.setCurrentIndex(self.cmaps.index(self.props[var]['cmap']))
        self.contcolor.setStyleSheet("background-color: {}".format(self.props[var]['color']))
        if self.props[var]['contours'] == 'map':
            self.contcheckmap.setChecked(True)
        elif self.props[var]['contours'] == 'color':
            self.contcheckcolor.setChecked(True)
        else:
            self.contchecknone.setChecked(True)
        if self.props[var]['label']:
            self.contlabel.setChecked(True)
        else:
            self.contlabel.setChecked(False)
        #processing
        self.resample.setValue(self.props[var]['resample'])
        self.filtersize.setValue(self.props[var]['median'])
        self.filtersigma.setValue(self.props[var]['gauss'])
        self.clipmin.setText(repr(self.props[var]['clipmin']))
        self.clipmax.setText(repr(self.props[var]['clipmax']))

    def on_var_changed(self, selected):
        self.var = self.data.dep[selected.indexes()[0].row()]
        self.set_var_props(self.var)
        if self.action3D.isChecked():
            self.plot()

    def apply_props(self):
        #levels
        self.props[self.var]['min'] = float(self.levelmin.text())
        self.props[self.var]['max'] = float(self.levelmax.text())
        self.props[self.var]['num'] = int(self.levelnum.text())
        self.props[self.var]['step'] = float(self.levelstep.text())
        if self.setlevels.isChecked():
            self.props[self.var]['levels'] = 'num'
        else:
            self.props[self.var]['levels'] = 'step'
        if self.linlevel.isChecked():
            self.props[self.var]['type'] = 'linear'
        else:
            self.props[self.var]['type'] = 'cdf'
        #style
        if self.fillstyle.isChecked():
            self.props[self.var]['fill'] = True
        else:
            self.props[self.var]['fill'] = False
        self.props[self.var]['opacity'] = self.opacity.value()
        self.props[self.var]['cmap'] = str(self.mapstyle.currentText())
        self.props[self.var]['color'] = str(self.contcolor.palette().color(1).name())
        if self.contcheckmap.isChecked():
            self.props[self.var]['contours'] = 'map'
        elif self.contcheckcolor.isChecked():
            self.props[self.var]['contours'] = 'color'
        else:
            self.props[self.var]['contours'] = ''
        if self.contlabel.isChecked():
            self.props[self.var]['label'] = True
        else:
            self.props[self.var]['label'] = False
        #processing
        self.props[self.var]['resample'] = self.resample.value()
        self.props[self.var]['median'] = self.filtersize.value()
        self.props[self.var]['gauss'] = self.filtersigma.value()
        self.props[self.var]['clipmin'] = float(self.clipmin.text())
        self.props[self.var]['clipmax'] = float(self.clipmax.text())
        self.plot()

    def restore_props(self):
        self.default_var_props(self.var)
        self.set_var_props(self.var)
        self.plot()

    def edit_options(self):
        dlg = OptionsForm(self)
        dlg.exec_()

    def plotpan(self):
        self.actionZoom.setChecked(False)
        self.mpl_toolbar.pan()

    def plotzoom(self):
        self.actionPan.setChecked(False)
        self.mpl_toolbar.zoom()

    def plotgrid(self):
        plt.grid()
        self._canvas.draw()

    def switch3d(self):
        if not self.action3D.isChecked():
            self._fig.clear()
            self._ax = self._fig.add_subplot(111)
        else:
            self._fig.clear()
            self._ax = self._fig.add_subplot(111, projection='3d')
        self.plot()

    def plot(self):
        self._ax.cla()
        if not self.action3D.isChecked():
            extent = self.data.get_extent()
            i = 0
            while self._model.item(i):
                if self._model.item(i).checkState():
                    CS = None
                    var = str(self._model.item(i).text())
                    # get data, smooth and clip
                    data = self.data.get_var(var,nan=np.float(self.settings.value("nan", "NaN", type=str)))
                    if self.props[var]['resample'] > 1:
                        data = np.ma.array(ndimage.zoom(data.filled(0), self.props[var]['resample']), mask=ndimage.zoom(data.mask, self.props[var]['resample'], order=0))
                    if self.props[var]['median'] > 1:
                        data = np.ma.array(ndimage.median_filter(data, size=self.props[var]['median']*self.props[var]['resample']), mask=data.mask)
                    if self.props[var]['gauss'] > 0:
                        data = np.ma.array(ndimage.gaussian_filter(data, sigma=self.props[var]['gauss']*self.props[var]['resample']), mask=data.mask)
                    data = np.ma.masked_outside(data, self.props[var]['clipmin'], self.props[var]['clipmax'])
                    if self.props[var]['fill']:
                        self._ax.imshow(data, interpolation='none', origin='lower', extent=extent, aspect='auto', cmap=plt.get_cmap(self.props[var]['cmap']), alpha=self.props[var]['opacity']/100.0)
                    if self.props[var]['type'] == 'linear':
                        if self.props[var]['levels'] == 'num':
                            clevels = np.linspace(self.props[var]['min'], self.props[var]['max'], self.props[var]['num'])
                        else:
                            # trick to include max in levels
                            clevels = np.arange(self.props[var]['min'], self.props[var]['max'] + 10**np.ceil(np.log10(np.abs(self.props[var]['max']))), self.props[var]['step'])
                    else:
                        # cdf based on histogram binned acording to the Freedman-Diaconis rule
                        v = np.sort(data.compressed())
                        IQR = v[int(round((v.size-1) * float(0.75)))] - v[int(round((v.size-1) * float(0.25)))]
                        bin_size = 2 * IQR * v.size**(-1.0/3)
                        nbins = int(round(max(self.props[var]['num'], (v[-1]-v[0]) / (bin_size+0.001))))
                        hist, bin_edges = np.histogram(v, bins=nbins)
                        cdf = np.cumsum(hist)
                        cdfx = np.cumsum(np.diff(bin_edges)) + bin_edges[:2].sum()/2
                        clevels = np.interp(np.linspace(cdf[0],cdf[-1],self.props[var]['num'] + 2)[1:-1], cdf, cdfx)
                    if self.props[var]['contours'] == 'map':
                        CS = self._ax.contour(self.data.get_xrange(self.props[var]['resample']), self.data.get_yrange(self.props[var]['resample']), data, clevels, cmap=plt.get_cmap(self.props[var]['cmap']))
                    elif self.props[var]['contours'] == 'color':
                        CS = self._ax.contour(self.data.get_xrange(self.props[var]['resample']), self.data.get_yrange(self.props[var]['resample']), data, clevels, colors=self.props[var]['color'])
                    if self.props[var]['label'] and CS:
                        self._ax.clabel(CS, fontsize=8, inline=1)
                i += 1

            self._ax.axis(extent)
            plt.title(self.data.label)
        else:
            # get data, smooth and clip
            data = self.data.get_var(self.var)
            if self.props[self.var]['resample'] > 1:
                data = np.ma.array(ndimage.zoom(data.filled(0), self.props[self.var]['resample']), mask=ndimage.zoom(data.mask, self.props[self.var]['resample'], order=0))
            if self.props[self.var]['median'] > 1:
                data = np.ma.array(ndimage.median_filter(data, size=self.props[self.var]['median']*self.props[self.var]['resample']), mask=data.mask)
            if self.props[self.var]['gauss'] > 0:
                data = np.ma.array(ndimage.gaussian_filter(data, sigma=self.props[self.var]['gauss']*self.props[self.var]['resample']), mask=data.mask)
            data = np.ma.masked_outside(data, self.props[self.var]['clipmin'], self.props[self.var]['clipmax'])
            x,y = np.meshgrid(self.data.get_xrange(self.props[self.var]['resample']), self.data.get_yrange(self.props[self.var]['resample']))
            self._ax.plot_surface(x, y, data.filled(np.NaN), vmin=data.min(), vmax=data.max(), cmap=plt.get_cmap(self.props[self.var]['cmap']), linewidth=0.5, alpha=self.props[self.var]['opacity']/100.0)
            self._ax.view_init(azim=235, elev=30)

        plt.xlabel(self.data.ind[self.data.xvar]['name'])
        plt.ylabel(self.data.ind[self.data.yvar]['name'])
        plt.tight_layout()
        self._canvas.draw()
Esempio n. 8
0
class Window(QtGui.QWidget):
    # G2 = nil

    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure)

        self.toolbar = NavigationToolbar(self.canvas, self)
        # self.toolbar.hide()

        # Just some button
        self.button = QtGui.QPushButton('Plot')
        self.button.clicked.connect(self.plot)

        self.button1 = QtGui.QPushButton('Zoom')
        self.button1.clicked.connect(self.zoom)

        self.button2 = QtGui.QPushButton('Pan')
        self.button2.clicked.connect(self.pan)

        self.button3 = QtGui.QPushButton('Home')
        self.button3.clicked.connect(self.home)

        self.button4 = QtGui.QPushButton('Home')
        self.button3.clicked.connect(self.home)
        # tabs = QtGui.QTabWidget()
        # tab1 = QtGui.QWidget()
        # tab2 = QtGui.QWidget()

        # set the layout
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)
        layout.addWidget(self.button)
        layout.addWidget(self.button1)
        layout.addWidget(self.button2)
        layout.addWidget(self.button3)

        self.setLayout(layout)

    def home(self):
        self.toolbar.home()

    def zoom(self):
        self.toolbar.zoom()

    def pan(self):
        self.toolbar.pan()

    def addData(self, G=None):
        self.G2

    def plot(self):
        ''' plot some random stuff '''
        G = nx.balanced_tree(3, 5)
        pos = graphviz_layout(G, prog='twopi', args='')
        # self.plt2.figure(figsize=(8, 8))
        nx.draw(G,
                pos,
                node_size=100,
                alpha=0.5,
                node_color="blue",
                with_labels=False)
        # data = [random.random() for i in range(25)]
        # ax = self.figure.add_subplot(111)
        # ax.hold(False)
        # ax.plot(data, '*-')
        self.canvas.draw()

    def addData(self, G=None):
        G2 = G
        print("G2 is ->", G2)
Esempio n. 9
0
class Window(Qt.QWidget):
    def __init__(self):
        super(Window, self).__init__()

        self.startButton = Qt.QPushButton()
        self.startButton.setFixedSize(100, 100)
        self.startButton.setIcon(Qt.QIcon('Green_Start.png'))
        self.startButton.setIconSize(Qt.QSize(75, 75))

        self.stopButton = Qt.QPushButton()
        self.stopButton.setFixedSize(100, 100)
        self.stopButton.setIcon(Qt.QIcon('Red_Stop.png'))
        self.stopButton.setIconSize(Qt.QSize(75, 75))

        self.vidThread = Qt.QThread()
        self.ardThread = Qt.QThread()
        self.vidThread.start()
        self.ardThread.start()

        self.vidTracking = VideoTracking()
        self.vidTracking.moveToThread(self.vidThread)

        self.arduino = Arduino()
        self.arduino.moveToThread(self.ardThread)

        self.stopButton.clicked.connect(lambda: self.arduino.stop())
        self.stopButton.clicked.connect(lambda: self.vidTracking.stop())
        self.startButton.clicked.connect(self.arduino.Run)
        self.startButton.clicked.connect(self.start_pressed)

        self.table = Qt.QTableWidget()
        self.table_rowCount = 0
        self.table.setRowCount(self.table_rowCount)
        self.table.setColumnCount(6)
        self.table.setHorizontalHeaderLabels([
            'Trial #', 'Date', 'Start Time', 'End Time', 'Duration (sec)',
            'Comments'
        ])
        #self.table.horizontalHeader().setResizeMode(Qt.QHeaderView.Stretch)
        self.table.horizontalHeader().setStretchLastSection(True)

        self.table.cellChanged.connect(self.cell_was_clicked)

        boldFont = Qt.QFont()
        boldFont.setBold(True)

        label1 = Qt.QLabel("Python Console Output")
        label1.setFont(boldFont)

        self.txtEdt1 = Qt.QTextEdit()
        self.txtEdt1.setReadOnly(True)

        # Install the custom output stream
        sys.stdout = EmittingStream(textWritten=self.normalOutputWritten)

        self.actButton1 = Qt.QPushButton(self.tr("&actButton1"))
        self.actButton1.setCheckable(True)
        self.actButton1.toggled.connect(
            lambda: self.arduino.actButton1(self.actButton1.isChecked()))
        self.actButton2 = Qt.QPushButton(self.tr("&actButton2"))
        self.actButton2.setCheckable(True)
        self.actButton2.toggled.connect(
            lambda: self.arduino.actButton2(self.actButton2.isChecked()))
        self.actButton3 = Qt.QPushButton(self.tr("&actButton3"))
        self.actButton3.setCheckable(True)
        self.actButton3.toggled.connect(
            lambda: self.arduino.actButton3(self.actButton3.isChecked()))
        self.actButton4 = Qt.QPushButton(self.tr("&actButton4"))
        self.actButton4.setCheckable(True)
        self.actButton4.toggled.connect(
            lambda: self.arduino.actButton4(self.actButton4.isChecked()))
        self.actButton5 = Qt.QPushButton(self.tr("&actButton5"))
        self.actButton5.setCheckable(True)
        self.actButton5.toggled.connect(
            lambda: self.arduino.actButton5(self.actButton5.isChecked()))
        self.actButton6 = Qt.QPushButton(self.tr("&actButton6"))
        self.actButton6.setCheckable(True)
        self.actButton6.toggled.connect(
            lambda: self.arduino.actButton6(self.actButton6.isChecked()))
        self.actButton7 = Qt.QPushButton(self.tr("&actButton7"))
        self.actButton7.setCheckable(True)
        self.actButton7.toggled.connect(
            lambda: self.arduino.actButton7(self.actButton7.isChecked()))
        self.actButton8 = Qt.QPushButton(self.tr("&actButton8"))
        self.actButton8.setCheckable(True)
        self.actButton8.toggled.connect(
            lambda: self.arduino.actButton8(self.actButton8.isChecked()))

        self.frame4 = Qt.QFrame()
        self.frame4.setFrameStyle(1)
        self.frame4.setFixedSize(350, 370)

        self.arena_setup_new_edit = Qt.QPushButton("New/Edit")
        self.arena_setup_new_edit.clicked.connect(self.new_edit_arena_setup)

        self.arena_setup_load = Qt.QPushButton("Load")
        self.arena_setup_load.clicked.connect(self.load_arena_setup)

        self.arena_setup_save = Qt.QPushButton("Save")
        self.arena_setup_save.clicked.connect(self.save_arena_setup)

        layout6 = Qt.QHBoxLayout()
        layout6.addWidget(self.arena_setup_new_edit)
        layout6.addWidget(self.arena_setup_load)
        layout6.addWidget(self.arena_setup_save)

        self.main_frame = Qt.QWidget()
        self.main_frame.setFixedSize(325, 325)
        self.fig = Figure((5.0, 4.0), dpi=100)
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self.main_frame)

        self.fig.canvas.mpl_connect("motion_notify_event", self.mouse_movement)

        self.fig_toolbar = NavigationToolbar(self.canvas, self.main_frame)
        self.fig_toolbar.hide()

        self.homeBtn = Qt.QPushButton()
        self.homeBtn.setFixedSize(25, 25)
        self.homeBtn.setIcon(Qt.QIcon('home.png'))
        self.homeBtn.setIconSize(Qt.QSize(20, 20))
        self.homeBtn.clicked.connect(self.home)

        self.panBtn = Qt.QPushButton()
        self.panBtn.setCheckable(True)
        self.panBtn.setFixedSize(25, 25)
        self.panBtn.setIcon(Qt.QIcon('move.png'))
        self.panBtn.setIconSize(Qt.QSize(20, 20))
        self.panBtn.clicked.connect(self.pan)

        self.zoomBtn = Qt.QPushButton()
        self.zoomBtn.setCheckable(True)
        self.zoomBtn.setFixedSize(25, 25)
        self.zoomBtn.setIcon(Qt.QIcon('zoom_to_rect.png'))
        self.zoomBtn.setIconSize(Qt.QSize(20, 20))
        self.zoomBtn.clicked.connect(self.zoom_to_rect)

        self.lblsBtn = Qt.QPushButton()
        self.lblsBtn.setCheckable(True)
        self.lblsBtn.setFixedSize(25, 25)
        self.lblsBtn.setIcon(Qt.QIcon('label_icon.png'))
        self.lblsBtn.setIconSize(Qt.QSize(20, 20))
        self.lblsBtn.clicked.connect(self.show_hide_labels)

        self.drawBtn = Qt.QPushButton()
        self.drawBtn.setFixedSize(25, 25)
        self.drawBtn.setIcon(Qt.QIcon('refresh_icon.jpeg'))
        self.drawBtn.setIconSize(Qt.QSize(20, 20))
        self.drawBtn.clicked.connect(self.redraw_arena_setup)

        self.coords_label = Qt.QLabel()
        self.coords_label.setAlignment(QtCore.Qt.AlignCenter)

        self.fig_statusbar = Qt.QStatusBar()
        self.fig_statusbar.setSizeGripEnabled(False)
        self.fig_statusbar.addWidget(self.homeBtn)
        self.fig_statusbar.addWidget(self.panBtn)
        self.fig_statusbar.addWidget(self.zoomBtn)
        self.fig_statusbar.addWidget(self.lblsBtn)
        self.fig_statusbar.addWidget(self.drawBtn)
        self.fig_statusbar.addWidget(self.coords_label, 1)

        frame_layout4 = Qt.QVBoxLayout()
        frame_layout4.addLayout(layout6)
        frame_layout4.addWidget(self.main_frame)
        frame_layout4.addWidget(self.fig_statusbar)
        self.frame4.setLayout(frame_layout4)

        self.radBtn1 = Qt.QRadioButton(
            self.tr("Connect to Raspberry Pi Camera"))
        self.radBtn1.setFont(boldFont)
        self.radBtn1.setChecked(False)
        self.radBtn1.toggled.connect(self.connect_to_camera)

        self.radBtn4 = Qt.QRadioButton(self.tr("Video Record Trial"))
        self.radBtn4.setChecked(False)
        self.radBtn4.setDisabled(True)
        self.radBtn4.toggled.connect(self.video_record_trial)

        self.lneEdt1 = Qt.QLineEdit()
        self.lneEdt1.setDisabled(True)
        self.lneEdt1.setText("example_video_name.mp4")

        self.lneEdt1.textChanged.connect(self.video_record_trial)

        self.new_edit1 = Qt.QPushButton("New/Edit")
        self.new_edit1.clicked.connect(self.new_edit_video_tracking_method)
        self.new_edit1.setDisabled(True)

        self.load1 = Qt.QPushButton("Load")
        self.load1.clicked.connect(self.load_video_tracking_method)
        self.load1.setDisabled(True)

        self.save1 = Qt.QPushButton("Save")
        self.save1.clicked.connect(self.save_video_tracking_method)
        self.save1.setDisabled(True)

        butLayout1 = Qt.QHBoxLayout()
        butLayout1.addWidget(self.new_edit1)
        butLayout1.addWidget(self.load1)
        butLayout1.addWidget(self.save1)

        self.frame1 = Qt.QFrame()
        self.frame1.setFrameStyle(1)
        self.frame1.setFixedSize(350, 140)

        frame_layout1 = Qt.QVBoxLayout()
        frame_layout1.addWidget(self.radBtn1)
        frame_layout1.addLayout(butLayout1)
        frame_layout1.addWidget(self.radBtn4)
        frame_layout1.addWidget(self.lneEdt1)
        self.frame1.setLayout(frame_layout1)

        self.radBtn2 = Qt.QRadioButton(self.tr("Load Video Recording"))
        self.radBtn2.setFont(boldFont)
        self.radBtn2.setChecked(False)
        self.radBtn2.toggled.connect(self.load_video_recording)

        self.btnLneEdt1 = ButtonLineEdit()
        self.btnLneEdt1.setReadOnly(True)
        self.btnLneEdt1.setDisabled(True)
        self.btnLneEdt1.buttonClicked.connect(self.find_video_recording)

        self.vid_len_label = Qt.QLabel(
            "Loaded video length / Trial Runtime (seconds):")
        self.vid_len_label.setDisabled(True)

        self.vid_len_spnBox = Qt.QSpinBox()
        self.vid_len_spnBox.setMaximum(86400)
        self.vid_len_spnBox.setDisabled(True)

        vidLenLayout = Qt.QFormLayout()
        vidLenLayout.addRow(self.vid_len_label, self.vid_len_spnBox)
        vidLenLayout.setLabelAlignment(QtCore.Qt.AlignRight)

        self.new_edit2 = Qt.QPushButton("New/Edit")
        self.new_edit2.clicked.connect(self.new_edit_video_tracking_method)
        self.new_edit2.setDisabled(True)

        self.load2 = Qt.QPushButton("Load")
        self.load2.clicked.connect(self.load_video_tracking_method)
        self.load2.setDisabled(True)

        self.save2 = Qt.QPushButton("Save")
        self.save2.clicked.connect(self.save_video_tracking_method)
        self.save2.setDisabled(True)

        butLayout2 = Qt.QHBoxLayout()
        butLayout2.addWidget(self.new_edit2)
        butLayout2.addWidget(self.load2)
        butLayout2.addWidget(self.save2)

        self.frame2 = Qt.QFrame()
        self.frame2.setFrameStyle(1)
        self.frame2.setFixedSize(350, 145)

        frame_layout2 = Qt.QVBoxLayout()
        frame_layout2.addWidget(self.radBtn2)
        frame_layout2.addWidget(self.btnLneEdt1)
        frame_layout2.addLayout(vidLenLayout)
        frame_layout2.addLayout(butLayout2)
        self.frame2.setLayout(frame_layout2)

        self.radBtn3 = Qt.QRadioButton(self.tr("Connect to Arduino"))
        self.radBtn3.setFont(boldFont)
        self.radBtn3.setChecked(False)
        self.radBtn3.toggled.connect(self.connect_to_arduino)

        self.new_edit3 = Qt.QPushButton("New/Edit")
        self.new_edit3.clicked.connect(self.new_edit_ard_method)
        self.new_edit3.setDisabled(True)

        self.load3 = Qt.QPushButton("Load")
        self.load3.clicked.connect(self.load_ard_method)
        self.load3.setDisabled(True)

        self.save3 = Qt.QPushButton("Save")
        self.save3.clicked.connect(self.save_ard_method)
        self.save3.setDisabled(True)

        butLayout3 = Qt.QHBoxLayout()
        butLayout3.addWidget(self.new_edit3)
        butLayout3.addWidget(self.load3)
        butLayout3.addWidget(self.save3)

        self.frame3 = Qt.QFrame()
        self.frame3.setFrameStyle(1)
        self.frame3.setFixedSize(350, 80)

        frame_layout3 = Qt.QVBoxLayout()
        frame_layout3.addWidget(self.radBtn3)
        frame_layout3.addLayout(butLayout3)
        self.frame3.setLayout(frame_layout3)

        self.group = Qt.QButtonGroup()
        self.group.addButton(self.radBtn1)
        self.group.addButton(self.radBtn2)
        self.group.setExclusive(False)

        self.lcd = QtGui.QLCDNumber()
        self.lcd.setFixedSize(140, 40)

        self.frame6 = Qt.QFrame()
        self.frame6.setFrameStyle(1)

        frame_layout6 = Qt.QHBoxLayout()
        frame_layout6.addWidget(self.lcd)
        self.frame6.setLayout(frame_layout6)

        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.timer_time)

        global s, m, h
        s = 0
        m = 0
        h = 0

        layout = Qt.QGridLayout()
        layout.addWidget(self.actButton1, 0, 0)
        layout.addWidget(self.actButton2, 1, 0)
        layout.addWidget(self.actButton3, 0, 1)
        layout.addWidget(self.actButton4, 1, 1)
        layout.addWidget(self.actButton5, 0, 2)
        layout.addWidget(self.actButton6, 1, 2)
        layout.addWidget(self.actButton7, 0, 3)
        layout.addWidget(self.actButton8, 1, 3)

        layout5 = Qt.QHBoxLayout()
        layout5.addWidget(self.startButton)
        layout5.addWidget(self.stopButton)

        self.frame5 = Qt.QFrame()
        self.frame5.setFrameStyle(1)

        frame_layout5 = Qt.QHBoxLayout()
        frame_layout5.addLayout(layout5)
        frame_layout5.addLayout(layout)
        self.frame5.setLayout(frame_layout5)

        layout1 = Qt.QHBoxLayout()
        layout1.addWidget(self.frame5)
        layout1.addWidget(self.frame6)

        layout2 = Qt.QVBoxLayout()
        layout2.addLayout(layout1)
        layout2.addWidget(self.table)
        layout2.addWidget(label1)
        layout2.addWidget(self.txtEdt1)

        layout5 = Qt.QVBoxLayout()
        layout5.addWidget(self.canvas)
        layout5.addWidget(self.fig_statusbar)
        self.main_frame.setLayout(layout5)

        layout3 = Qt.QVBoxLayout()
        layout3.addWidget(self.frame4)
        layout3.addWidget(self.frame1)
        layout3.addWidget(self.frame2)
        layout3.addWidget(self.frame3)
        layout3.addStretch(True)

        layout4 = Qt.QHBoxLayout()
        layout4.addLayout(layout3)
        layout4.addLayout(layout2)

        self.setLayout(layout4)

        global global_results, vidTrack_setup_parameters, ard_setup_parameters, arena_setup_parameters, camera, video_name, recording, record_name
        global_results = {}
        vidTrack_setup_parameters = None
        ard_setup_parameters = None
        arena_setup_parameters = None
        camera = None
        video_name = None
        recording = False
        record_name = None

    def __del__(self):
        # Restore sys.stdout
        sys.stdout = sys.__stdout__

    def normalOutputWritten(self, text):
        self.txtEdt1.append(text)

    def cell_was_clicked(self):
        global global_results
        try:
            current_row = self.table.currentRow()
            current_column = self.table.currentColumn()
            current_item_text = self.table.currentItem().text()
            if current_column == 5:
                global_results[str(current_row + 1)]["trial_info"].update(
                    {"Comments": current_item_text})
        except:
            pass

    def new_edit_arena_setup(self):
        global arena_setup_parameters
        if arena_setup_parameters == None:
            try:
                from setup_arena_picture import arena_setup_parameters
            except:
                pass
        self.new_edit_arena = setup_arena_picture.Window(
            cam=camera, vid_name=video_name, arena_sp=arena_setup_parameters)
        self.new_edit_arena.show()
        arena_setup_parameters = None

    def load_arena_setup(self):
        try:
            global arena_setup_parameters
            name = Qt.QFileDialog.getOpenFileName(self, 'Load Arena Setup')
            with open(name, 'r') as f:
                arena_setup_parameters = eval(f.read())
            print("loaded arena setup: %s" % (arena_setup_parameters))
        except:
            pass

    def save_arena_setup(self):
        global arena_setup_parameters
        try:
            try:
                from setup_arena_picture import arena_setup_parameters
            except:
                pass
            name = Qt.QFileDialog.getSaveFileName(self, 'Save Arena Setup')
            with open(name, 'w') as text_file:
                text_file.write(str(arena_setup_parameters))
            print("arena setup saved %s" % (arena_setup_parameters))
        except:
            pass

    def home(self):
        self.fig_toolbar.home()

    def pan(self):
        self.fig_toolbar.pan()

    def zoom_to_rect(self):
        self.fig_toolbar.zoom()

    def show_hide_labels(self):
        global arena_setup_parameters
        if self.lblsBtn.isChecked():
            # add labels to the grid squares
            self.grid_labels = []
            for j in range(self.num_height_divs):
                y = self.height_div / 2 + j * self.height_div
                for i in range(self.num_width_divs):
                    x = self.width_div / 2. + float(i) * self.width_div
                    if arena_setup_parameters['arena_pic_name'] != "no picture":
                        grid_label = self.axes.text(x,
                                                    y, ("(%d,%d)" % (i, j)),
                                                    fontsize=6,
                                                    color='w',
                                                    ha='center',
                                                    va='center')
                    else:
                        grid_label = self.axes.text(x,
                                                    y, ("(%d,%d)" % (i, j)),
                                                    fontsize=6,
                                                    color='b',
                                                    ha='center',
                                                    va='center')
                    self.grid_labels.append(grid_label)
                    self.canvas.draw()
        elif not self.lblsBtn.isChecked():
            for label in self.grid_labels:
                label.remove()
            self.canvas.draw()

    def redraw_arena_setup(self):
        global arena_setup_parameters

        if arena_setup_parameters == None:
            from setup_arena_picture import arena_setup_parameters

        self.lblsBtn.setChecked(False)

        self.arena_pic_name = arena_setup_parameters['arena_pic_name']
        try:
            self.arena_pic = mpimg.imread(self.arena_pic_name)
        except:
            pass
        self.arena_width = arena_setup_parameters['arena_width']
        self.arena_height = arena_setup_parameters['arena_height']
        self.width_div = arena_setup_parameters['width_div']
        self.height_div = arena_setup_parameters['height_div']
        self.num_width_divs = int(round(self.arena_width / self.width_div, 0))
        self.num_height_divs = int(
            round(self.arena_height / self.height_div, 0))

        self.fig.clear()

        self.axes = self.fig.add_subplot(111)
        try:
            self.axes.imshow(self.arena_pic,
                             origin="lower",
                             extent=(0, self.arena_width, 0,
                                     self.arena_height))
        except:
            npArray = np.array([[[0, 0, 0, 0]]], dtype="uint8")
            self.axes.imshow(npArray,
                             origin="lower",
                             extent=(0, self.arena_width, 0,
                                     self.arena_height))

        self.axes.set_xticks(
            np.arange(0, (self.arena_width + self.width_div), self.width_div))
        self.axes.set_yticks(
            np.arange(0, (self.arena_height + self.height_div),
                      self.height_div))
        self.axes.tick_params(axis="both", which="major", labelsize="6")

        self.axes.grid(which="major", axis="both", linestyle='-', color='r')
        self.axes.xaxis.tick_top()
        self.axes.invert_yaxis()
        self.axes.set_xlabel("Arena Width (cm)", fontsize=8)
        self.axes.set_ylabel("Arena Height (cm)", fontsize=8)
        self.axes.tick_params(axis="both", which="major", labelsize=6)

        self.canvas.draw()

    def mouse_movement(self, event):
        try:
            self.coords_label.setText("x=%.3f,   y=%.3f" %
                                      (event.xdata, event.ydata))
        except:
            if not self.coords_label.text == "":
                self.coords_label.setText("")
            else:
                pass

    def connect_to_camera(self):
        global camera, vidTrack_setup_parameters
        if self.radBtn1.isChecked():
            camera = True
            self.new_edit1.setDisabled(False)
            self.load1.setDisabled(False)
            self.save1.setDisabled(False)
            self.radBtn4.setDisabled(False)

            self.radBtn2.setChecked(False)
            #self.load_video_recording()

        elif not self.radBtn1.isChecked():
            camera = None
            vidTrack_setup_parameters = None
            self.new_edit1.setDisabled(True)
            self.load1.setDisabled(True)
            self.save1.setDisabled(True)
            self.radBtn4.setDisabled(True)
            self.lneEdt1.setDisabled(True)

    def new_edit_video_tracking_method(self):
        global camera, video_name, vidTrack_setup_parameters
        if vidTrack_setup_parameters == None:
            try:
                from Camera_Wizard_v2 import vidTrack_setup_parameters
            except:
                pass
        self.cwiz = Camera_Wizard_v2.CameraWizard(
            cam=camera,
            vid_name=video_name,
            vidTrack_sp=vidTrack_setup_parameters)
        self.cwiz.show()
        vidTrack_setup_parameters = None

    def load_video_tracking_method(self):
        try:
            global vidTrack_setup_parameters
            name = Qt.QFileDialog.getOpenFileName(self,
                                                  'Load Video Tracking Setup')
            with open(name, 'r') as f:
                vidTrack_setup_parameters = eval(f.read())
            print("loaded video tracking setup: %s" %
                  (vidTrack_setup_parameters))
        except:
            pass

    def save_video_tracking_method(self):
        global vidTrack_setup_parameters
        try:
            if vidTrack_setup_parameters == None:
                try:
                    from Camera_Wizard_v2 import vidTrack_setup_parameters
                except:
                    pass
            name = Qt.QFileDialog.getSaveFileName(self,
                                                  'Save Video Tracking Setup')
            with open(name, 'w') as text_file:
                text_file.write(str(vidTrack_setup_parameters))
            print("video tracking setup saved %s" %
                  (vidTrack_setup_parameters))
        except:
            pass

    def video_record_trial(self):
        global recording, record_name
        if self.radBtn4.isChecked():
            self.lneEdt1.setDisabled(False)
            recording = True
            record_name = self.lneEdt1.text()
        elif not self.radBtn4.isChecked():
            self.lneEdt1.setDisabled(True)
            recording = False
            record_name = None

    def load_video_recording(self):
        global video_name, vidTrack_setup_parameters
        if self.radBtn2.isChecked():
            self.btnLneEdt1.setDisabled(False)
            self.radBtn4.setChecked(False)
            self.radBtn4.setDisabled(False)

            self.radBtn1.setChecked(False)
            #self.connect_to_camera()

        elif not self.radBtn2.isChecked():
            video_name = None
            vidTrack_setup_parameters = None
            self.btnLneEdt1.clear()
            self.btnLneEdt1.setDisabled(True)
            self.vid_len_label.setDisabled(True)
            self.vid_len_spnBox.clear()
            self.vid_len_spnBox.setDisabled(True)
            self.new_edit2.setDisabled(True)
            self.load2.setDisabled(True)
            self.save2.setDisabled(True)

    def find_video_recording(self):
        try:
            global video_name
            video_name = Qt.QFileDialog.getOpenFileName(
                self, 'Find Video Recording')
            self.btnLneEdt1.setText(video_name)
            self.vid_len_label.setDisabled(False)
            self.vid_len_spnBox.setDisabled(False)
            self.new_edit2.setDisabled(False)
            self.load2.setDisabled(False)
            self.save2.setDisabled(False)
            print("video name: %s" % (video_name))
        except:
            pass

    def connect_to_arduino(self):
        global a, ard_setup_parameters
        if self.radBtn3.isChecked():
            try:
                from nanpy import (SerialManager, ArduinoApi)
                connection = SerialManager()
                a = ArduinoApi(connection=connection)
                self.new_edit3.setDisabled(False)
                self.load3.setDisabled(False)
                self.save3.setDisabled(False)
            except:
                print("Failed to connect to Arduino")
                self.radBtn3.setChecked(False)  # change back to False
        elif not self.radBtn3.isChecked():
            try:
                del a
            except:
                pass
            ard_setup_parameters = None
            self.new_edit3.setDisabled(True)
            self.load3.setDisabled(True)
            self.save3.setDisabled(True)

    def new_edit_ard_method(self):
        global ard_setup_parameters
        if ard_setup_parameters == None:
            try:
                from Arduino_Wizard_v2 import ard_setup_parameters
            except:
                pass
        self.awiz = Arduino_Wizard_v2.ArduinoWizard(
            arduino_sp=ard_setup_parameters)
        self.awiz.show()
        ard_setup_parameters = None

    def load_ard_method(self):
        global ard_setup_parameters
        try:
            name = Qt.QFileDialog.getOpenFileName(self, 'Load DAAC setup')
            with open(name, 'r') as f:
                ard_setup_parameters = eval(f.read())
            print("loaded DAAC setup: %s" % (ard_setup_parameters))
        except:
            pass

    def save_ard_method(self):
        global ard_setup_parameters
        try:
            if ard_setup_parameters == None:
                try:
                    from Arduino_Wizard_v2 import ard_setup_parameters
                except:
                    pass
            name = Qt.QFileDialog.getSaveFileName(self, 'Save DAAC setup')
            with open(name, 'w') as text_file:
                text_file.write(str(ard_setup_parameters))
            print("DAAC setup saved %s" % (ard_setup_parameters))
        except:
            pass

    def timer_start(self):
        global s, m, h

        self.timer.start(1000)

    def timer_time(self):
        global s, m, h

        if s < 59:
            s += 1
        else:
            if m < 59:
                s = 0
                m += 1
            elif m == 59 and h < 24:
                h += 1
                m = 0
                s = 0
            else:
                self.timer.stop()

        time = "{0}:{1}:{2}".format(h, m, s)

        self.lcd.setDigitCount(len(time))
        self.lcd.display(time)
        self.activateWindow()

    def timer_reset(self):
        global s, m, h

        self.timer.stop()

        s = 0
        m = 0
        h = 0

        time = "{0}:{1}:{2}".format(h, m, s)

        self.lcd.setDigitCount(len(time))
        self.lcd.display(time)

    def start_pressed(self):
        global global_results, ard_results, _isRunning2, vidTrack_setup_parameters, ard_setup_parameters

        date = strftime("%Y-%m-%d")
        start_time = strftime("%H:%M:%S")

        self.timer_reset()
        self.timer_start()

        if (self.radBtn1.isChecked() or self.radBtn2.isChecked()):
            trck = self.vidTracking.Run()

        while _isRunning2:
            Qt.qApp.processEvents()

        self.timer.stop()

        end_time = strftime("%H:%M:%S")

        self.actButton1.setChecked(False)
        self.actButton2.setChecked(False)
        self.actButton3.setChecked(False)
        self.actButton4.setChecked(False)
        self.actButton5.setChecked(False)
        self.actButton6.setChecked(False)
        self.actButton7.setChecked(False)
        self.actButton8.setChecked(False)

        vidTrack_results = {}
        trial_info = {}
        try:
            if (vidTrack_setup_parameters['video_tracking_algorithm']
                    == "Frame Differencing") or (
                        vidTrack_setup_parameters['video_tracking_algorithm']
                        == "MOG"):
                if self.radBtn1.isChecked() or (
                        self.radBtn2.isChecked() and
                    (int(self.vid_len_spnBox.value() == 0))):
                    vidTrack_results['run_time'] = trck[2]
                    trial_info['Trial_Duration'] = trck[2][-1]
                    vidTrack_results['vid_pts_time'] = trck[0]
                elif self.radBtn2.isChecked() and (int(
                        self.vid_len_spnBox.value()) != 0):
                    video_time_calibration_factor = trck[2][-1] / int(
                        self.vid_len_spnBox.value())
                    vidTrack_results['run_time'] = []
                    for time in trck[2]:
                        mod_time = round(time / video_time_calibration_factor,
                                         2)
                        vidTrack_results['run_time'].append(mod_time)
                    trial_info['Trial_Duration'] = vidTrack_results[
                        'run_time'][-1]
                    vidTrack_results['vid_pts_time'] = []
                    for time in trck[0]:
                        mod_time = round(time / video_time_calibration_factor,
                                         2)
                        vidTrack_results["vid_pts_time"].append(mod_time)
                vidTrack_results['position'] = trck[1]
            elif vidTrack_setup_parameters[
                    'video_tracking_algorithm'] == "None":
                if self.radBtn1.isChecked() or (
                        self.radBtn2.isChecked() and
                    (int(self.vid_len_spnBox.value()) == 0)):
                    vidTrack_results['run_time'] = trck
                    trial_info['Trial_Duration'] = trck[-1]
                elif self.radBtn2.isChecked() and (int(
                        self.vid_len_spnBox.value()) != 0):
                    video_time_calibration_factor = (
                        trck[-1] / int(self.vid_len_spnBox.value()))
                    vidTrack_results['vid_pts_time'] = []
                    for time in trck[0]:
                        mod_time = round(time / video_time_calibration_factor,
                                         2)
                        vidTrack_results['vid_pts_time'].append(mod_time)
                    trial_info['Trial_Duration'] = vidTrack_results[
                        'run_time'][-1]
        except:
            pass

        try:
            try:
                duration = str(trial_info['Trial_Duration'])
            except:
                duration = str(ard_results['ard_loop_time'][-1])
        except:
            duration = str(0)

        trial_info["Date"] = date
        trial_info["Start_Time"] = start_time
        trial_info["End_Time"] = end_time
        trial_info["Trial_Duration"] = duration

        self.table_rowCount += 1
        self.table.setRowCount(self.table_rowCount)

        global_results[str(self.table_rowCount)] = {}
        global_results[str(self.table_rowCount)]["trial_info"] = trial_info
        try:
            global_results[str(
                self.table_rowCount)]["results"] = vidTrack_results
            global_results[str(
                self.table_rowCount)]["results"].update(ard_results)
            try:
                ard_results = {}
                global_results[str(
                    self.table_rowCount)]["results"].update(ard_results)
            except:
                pass
        except:
            pass

        self.table.setItem(self.table_rowCount - 1, 0,
                           Qt.QTableWidgetItem(str(self.table_rowCount)))
        self.table.setItem(self.table_rowCount - 1, 1,
                           Qt.QTableWidgetItem(date))
        self.table.setItem(self.table_rowCount - 1, 2,
                           Qt.QTableWidgetItem(start_time))
        self.table.setItem(self.table_rowCount - 1, 3,
                           Qt.QTableWidgetItem(end_time))
        self.table.setItem(self.table_rowCount - 1, 4,
                           Qt.QTableWidgetItem(duration))
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(1150, 655)
        MainWindow.setMinimumSize(QtCore.QSize(1500, 250))
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.gridLayout = QtGui.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
        self.pushButton_2 = QtGui.QPushButton(self.centralwidget)
        self.pushButton_2.setMinimumSize(QtCore.QSize(0, 30))
        self.pushButton_2.setMaximumSize(QtCore.QSize(70, 16777215))
        font = QtGui.QFont()
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_2.setFont(font)
        self.pushButton_2.setLayoutDirection(QtCore.Qt.RightToLeft)
        self.pushButton_2.setObjectName(_fromUtf8("pushButton_2"))
        self.pushButton_2.clicked.connect(self.zoom)  ########### zoom 함수 연결
        self.gridLayout.addWidget(self.pushButton_2, 2, 1, 1, 1)
        self.pushButton = QtGui.QPushButton(self.centralwidget)
        self.pushButton.setMinimumSize(QtCore.QSize(0, 30))
        self.pushButton.setMaximumSize(QtCore.QSize(70, 16777215))
        font = QtGui.QFont()
        font.setBold(True)
        font.setWeight(75)
        self.pushButton.setFont(font)
        self.pushButton.setLayoutDirection(QtCore.Qt.RightToLeft)
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.pushButton.clicked.connect(self.pan)  ###########pan 함수 연결
        self.gridLayout.addWidget(self.pushButton, 2, 2, 1, 1)
        self.pushButton_3 = QtGui.QPushButton(self.centralwidget)
        self.pushButton_3.setMinimumSize(QtCore.QSize(0, 30))
        self.pushButton_3.setMaximumSize(QtCore.QSize(70, 16777215))
        font = QtGui.QFont()
        font.setBold(True)
        font.setWeight(75)
        self.pushButton_3.setFont(font)
        self.pushButton_3.setLayoutDirection(QtCore.Qt.RightToLeft)
        self.pushButton_3.setObjectName(_fromUtf8("pushButton_3"))
        self.pushButton_3.clicked.connect(self.home)  ##########home 함수 연결
        self.gridLayout.addWidget(self.pushButton_3, 2, 3, 1, 1)
        self.frame_4 = QtGui.QFrame(self.centralwidget)
        self.frame_4.setMinimumSize(QtCore.QSize(150, 0))
        self.frame_4.setMaximumSize(QtCore.QSize(16777215, 40))
        self.frame_4.setFrameShape(QtGui.QFrame.StyledPanel)
        self.frame_4.setFrameShadow(QtGui.QFrame.Plain)
        self.frame_4.setLineWidth(1)
        self.frame_4.setObjectName(_fromUtf8("frame_4"))
        self.horizontalLayout = QtGui.QHBoxLayout(self.frame_4)
        self.horizontalLayout.setContentsMargins(-1, 0, -1, -1)
        self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
        self.label = QtGui.QLabel(self.frame_4)
        self.label.setMinimumSize(QtCore.QSize(0, 35))
        self.label.setMaximumSize(QtCore.QSize(40, 30))
        font = QtGui.QFont()
        font.setPointSize(12)
        font.setBold(True)
        font.setWeight(75)
        self.label.setFont(font)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName(_fromUtf8("label"))
        self.horizontalLayout.addWidget(self.label)
        self.dateEdit = QtGui.QDateEdit(self.frame_4)
        self.dateEdit.setMinimumSize(QtCore.QSize(0, 30))
        self.dateEdit.setMaximumSize(QtCore.QSize(121, 20))
        font = QtGui.QFont()
        font.setPointSize(12)
        font.setBold(True)
        font.setWeight(75)
        self.dateEdit.setFont(font)
        self.dateEdit.setAlignment(QtCore.Qt.AlignCenter)
        self.dateEdit.setObjectName(_fromUtf8("dateEdit"))
        self.dateEdit.setDateTime(
            QtCore.QDateTime.currentDateTime())  ########## 현재 날짜로 업데이트
        self.dateEdit.setCalendarPopup(True)  ########## 캘린더 팝업
        self.dateEdit.dateChanged.connect(
            self.ShowDate)  ########## 선택한 날짜로 데이터 업데이트
        self.horizontalLayout.addWidget(self.dateEdit)
        self.label_2 = QtGui.QLabel(self.frame_4)
        self.label_2.setMinimumSize(QtCore.QSize(0, 35))
        self.label_2.setMaximumSize(QtCore.QSize(81, 30))
        font = QtGui.QFont()
        font.setPointSize(12)
        font.setBold(True)
        font.setWeight(75)
        self.label_2.setFont(font)
        self.label_2.setAlignment(QtCore.Qt.AlignCenter)
        self.label_2.setObjectName(_fromUtf8("label_2"))
        self.horizontalLayout.addWidget(self.label_2)
        self.textEdit = QtGui.QTextEdit(self.frame_4)
        self.textEdit.setMinimumSize(QtCore.QSize(600, 30))
        self.textEdit.setMaximumSize(QtCore.QSize(16777215, 20))
        font = QtGui.QFont()
        font.setPointSize(12)
        font.setBold(True)
        font.setWeight(75)
        self.textEdit.setFont(font)
        self.textEdit.setFrameShape(QtGui.QFrame.StyledPanel)
        self.textEdit.setObjectName(_fromUtf8("textEdit"))
        self.horizontalLayout.addWidget(self.textEdit)
        self.comboBox = QtGui.QComboBox(self.frame_4)
        self.comboBox.setMinimumSize(QtCore.QSize(0, 30))
        self.comboBox.setMaximumSize(QtCore.QSize(16777215, 20))
        font = QtGui.QFont()
        font.setPointSize(12)
        font.setBold(True)
        font.setWeight(75)
        self.comboBox.setFont(font)
        self.comboBox.setObjectName(_fromUtf8("comboBox"))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.addItem(_fromUtf8(""))
        self.comboBox.activated.connect(self.convert_utc)
        self.horizontalLayout.addWidget(self.comboBox)
        self.gridLayout.addWidget(self.frame_4, 0, 0, 1, 4)
        self.verticalLayout = QtGui.QVBoxLayout()
        self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
        self.fig = plt.figure()  ########## figure 만들기
        self.canvas = FigureCanvas(self.fig)  ########## canvas 만들기
        self.verticalLayout.addWidget(self.canvas)  ########## figure 삽입
        self.toolbar = NavigationToolbar(self.canvas,
                                         MainWindow)  ##########툴바 생성
        self.toolbar.hide()  ##########툴바 숨김
        self.gridLayout.addLayout(self.verticalLayout, 1, 0, 1, 4)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1150, 21))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        self.menuOpen = QtGui.QMenu(self.menubar)
        self.menuOpen.setObjectName(_fromUtf8("menuOpen"))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)
        self.actionFile = QtGui.QAction(MainWindow)
        self.actionFile.setObjectName(_fromUtf8("actionFile"))
        self.actionFile.triggered.connect(
            self.OpenFile)  ########## OpenFile 연결
        self.actionDirectory = QtGui.QAction(MainWindow)
        self.actionDirectory.setObjectName(_fromUtf8("actionDirectory"))
        self.actionDirectory.triggered.connect(
            self.OpenDirectory)  ########## OpenDirectory 연결
        self.menuOpen.addAction(self.actionFile)
        self.menuOpen.addAction(self.actionDirectory)
        self.menubar.addAction(self.menuOpen.menuAction())

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
        self.pushButton_2.setText(_translate("MainWindow", "ZOOM", None))
        self.pushButton.setText(_translate("MainWindow", "PAN", None))
        self.pushButton_3.setText(_translate("MainWindow", "HOME", None))
        self.label.setText(_translate("MainWindow", "Date", None))
        self.label_2.setText(_translate("MainWindow", "Duration", None))
        self.comboBox.setCurrentIndex(14)
        self.comboBox.setItemText(0,
                                  _translate("MainWindow", "UTC -12:00", None))
        self.comboBox.setItemText(1,
                                  _translate("MainWindow", "UTC -11:00", None))
        self.comboBox.setItemText(2,
                                  _translate("MainWindow", "UTC -10:00", None))
        self.comboBox.setItemText(3,
                                  _translate("MainWindow", "UTC -09:30", None))
        self.comboBox.setItemText(4,
                                  _translate("MainWindow", "UTC -09:00", None))
        self.comboBox.setItemText(5,
                                  _translate("MainWindow", "UTC -08:00", None))
        self.comboBox.setItemText(6,
                                  _translate("MainWindow", "UTC -07:00", None))
        self.comboBox.setItemText(7,
                                  _translate("MainWindow", "UTC -06:00", None))
        self.comboBox.setItemText(8,
                                  _translate("MainWindow", "UTC -05:00", None))
        self.comboBox.setItemText(9,
                                  _translate("MainWindow", "UTC -04:00", None))
        self.comboBox.setItemText(10,
                                  _translate("MainWindow", "UTC -03:30", None))
        self.comboBox.setItemText(11,
                                  _translate("MainWindow", "UTC -03:00", None))
        self.comboBox.setItemText(12,
                                  _translate("MainWindow", "UTC -02:00", None))
        self.comboBox.setItemText(13,
                                  _translate("MainWindow", "UTC -01:00", None))
        self.comboBox.setItemText(14,
                                  _translate("MainWindow", "UTC +00:00", None))
        self.comboBox.setItemText(15,
                                  _translate("MainWindow", "UTC +01:00", None))
        self.comboBox.setItemText(16,
                                  _translate("MainWindow", "UTC +02:00", None))
        self.comboBox.setItemText(17,
                                  _translate("MainWindow", "UTC +03:00", None))
        self.comboBox.setItemText(18,
                                  _translate("MainWindow", "UTC +03:30", None))
        self.comboBox.setItemText(19,
                                  _translate("MainWindow", "UTC +04:00", None))
        self.comboBox.setItemText(20,
                                  _translate("MainWindow", "UTC +04:30", None))
        self.comboBox.setItemText(21,
                                  _translate("MainWindow", "UTC +05:00", None))
        self.comboBox.setItemText(22,
                                  _translate("MainWindow", "UTC +05:30", None))
        self.comboBox.setItemText(23,
                                  _translate("MainWindow", "UTC +05:45", None))
        self.comboBox.setItemText(24,
                                  _translate("MainWindow", "UTC +06:00", None))
        self.comboBox.setItemText(25,
                                  _translate("MainWindow", "UTC +06:30", None))
        self.comboBox.setItemText(26,
                                  _translate("MainWindow", "UTC +07:00", None))
        self.comboBox.setItemText(27,
                                  _translate("MainWindow", "UTC +08:00", None))
        self.comboBox.setItemText(28,
                                  _translate("MainWindow", "UTC +08:30", None))
        self.comboBox.setItemText(29,
                                  _translate("MainWindow", "UTC +08:45", None))
        self.comboBox.setItemText(30,
                                  _translate("MainWindow", "UTC +09:00", None))
        self.comboBox.setItemText(31,
                                  _translate("MainWindow", "UTC +09:30", None))
        self.comboBox.setItemText(32,
                                  _translate("MainWindow", "UTC +10:00", None))
        self.comboBox.setItemText(33,
                                  _translate("MainWindow", "UTC +10:30", None))
        self.comboBox.setItemText(34,
                                  _translate("MainWindow", "UTC +11:00", None))
        self.comboBox.setItemText(35,
                                  _translate("MainWindow", "UTC +12:00", None))
        self.comboBox.setItemText(36,
                                  _translate("MainWindow", "UTC +12:45", None))
        self.comboBox.setItemText(37,
                                  _translate("MainWindow", "UTC +13:00", None))
        self.comboBox.setItemText(38,
                                  _translate("MainWindow", "UTC +14:00", None))
        self.menuOpen.setTitle(_translate("MainWindow", "Open", None))
        self.actionFile.setText(_translate("MainWindow", "File", None))
        self.actionDirectory.setText(
            _translate("MainWindow", "Directory", None))

    def convert_utc(self):
        global utc_timezone
        temp = self.comboBox.currentText().split(" ")[1]
        if temp[0] == '-':
            utc_timezone = float(temp[0:3]) - float(temp[4:6]) / 60
        else:
            utc_timezone = float(temp[0:3]) + float(temp[4:6]) / 60

        if time_list is not None:
            int_time_list = []
            del int_time_list[:]
            for i in time_list:
                convert_time = self.convert_utc_timezone(i, utc_timezone)
                if convert_time.find('-') >= 0:
                    temp = convert_time.split('-')[0] + convert_time.split(
                        '-')[1] + convert_time.split('-')[2]
                    int_time_list.append(temp)

            min_time = min(int_time_list)[0:4] + '/' + min(
                int_time_list)[4:6] + '/' + min(int_time_list)[6:8]
            max_time = max(int_time_list)[0:4] + '/' + max(
                int_time_list)[4:6] + '/' + max(int_time_list)[6:8]
            self.textEdit.setText(min_time + ' ~ ' + max_time)  ###duration 설정
        else:
            pass

        self.View()

    def convert_utc_timezone(self, get_time, gap):
        get_time = get_time.replace("-", " ")
        get_time = get_time.replace(":", " ")
        temp = datetime(
            int(get_time.split(' ')[0]), int(get_time.split(' ')[1]),
            int(get_time.split(' ')[2]), int(get_time.split(' ')[3]),
            int(get_time.split(' ')[4]), int(get_time.split(' ')[5]), 0)
        convert_time = temp + timedelta(hours=gap)

        return str(convert_time)

    def zoom(self):
        self.toolbar.zoom()

    def pan(self):
        self.toolbar.pan()

    def home(self):
        self.toolbar.home()

    def ShowDate(self):
        date = self.dateEdit.date()
        string_date = str(date.toPyDate())
        Date["year"] = string_date.split('-')[0]
        Date["month"] = string_date.split('-')[1]
        Date["day"] = string_date.split('-')[2]

        self.View()

    def OpenFile(self):
        find = ['Onhub', 'Database', 'Amazon Echo']
        file_list = []
        del file_list[:]  #리스트 초기화
        del device_list[:]
        device_list.append('')  # y축 한 줄 띄려고 추가

        reload(sys)
        sys.setdefaultencoding('utf-8')

        FilePath = QtGui.QFileDialog.getOpenFileName()

        if FilePath:
            if FilePath[-4:] == '.csv':  # 확장자로 csv 파일만 필터링
                f = open(FilePath, 'r')
                first = f.readline().split(',')[0].split('-')[0]

                if first.split('(')[0] in find:  # 분석 대상 파일 필터링
                    file_list.append(FilePath)
                    device_list.append(first)
                f.close()

            self.Analyze_Data(file_list)
        else:
            pass

        self.init_view()

    def OpenDirectory(self):
        reload(sys)
        sys.setdefaultencoding('utf-8')

        DirPath = str(QtGui.QFileDialog.getExistingDirectory())

        if DirPath:
            self.Directory_Search(DirPath)
        else:
            pass

        self.init_view()

    def Directory_Search(self, DirPath):
        find = ['Onhub', 'Database', 'Amazon Echo']
        file_list = []
        del file_list[:]  #리스트 초기화
        del device_list[:]

        device_list.append('')  # y축 한 줄 띄려고 추가
        for (path, dir, files) in os.walk(
                unicode(DirPath)):  #unicode(DirPath): 한글 경로 가능하게
            for filename in files:
                if filename[-4:] == '.csv':  #확장자로 csv 파일만 필터링
                    f = open(os.path.join(path, filename), 'r')
                    first = f.readline()
                    if first[0:5] == 'Onhub':  #분석 대상 파일 필터링
                        file_list.append(os.path.join(path, filename))
                        device_list.append(first.split(',')[0].split('-')[0])
                    elif first[0:8] == 'Database':
                        file_list.append(os.path.join(path, filename))
                        device_list.append(
                            first.split('_')[0] + '(' +
                            first.split('(')[1].split('-')[0])
                    elif first[0:11] == 'Amazon Echo':
                        file_list.append(os.path.join(path, filename))
                        device_list.append(first.split(',')[0].split('-')[0])
                    f.close()

        self.Analyze_Data(file_list)

    def Analyze_Data(self, file_list):
        empty_list = []
        out_data["onhub_disconnect"] = empty_list
        out_data["onhub_connect"] = empty_list
        out_data["amazon_echo"] = empty_list
        out_data["Database"] = empty_list
        in_data = {}  #기기별 모든 데이터가 포함되어 있는 딕셔너리
        del time_list[:]
        index = 1
        for i in range(1, len(device_list)):
            data = self.Read_Data(file_list[i - 1], time_list, index)  #모든 데이터
            if in_data is None:
                in_data[device_list[i]] = data
            else:
                if device_list[i] in in_data:
                    in_data[device_list[i]] = data
                else:
                    in_data[device_list[i]] = data
            index += 1

        int_time_list = []
        del int_time_list[:]
        for i in time_list:
            if i.find('-') >= 0:
                temp = i.split('-')[0] + i.split('-')[1] + i.split('-')[2]
                int_time_list.append(temp)

        min_time = min(int_time_list)[0:4] + '/' + min(
            int_time_list)[4:6] + '/' + min(int_time_list)[6:8]
        max_time = max(int_time_list)[0:4] + '/' + max(
            int_time_list)[4:6] + '/' + max(int_time_list)[6:8]
        self.textEdit.setText(min_time + ' ~ ' + max_time)  ###duration 설정

        connect = []
        disconnect = []
        database = []
        echo = []

        for key in in_data:
            if key[0:5] == 'Onhub':
                temp1 = in_data[key]  #temp1은 각 기기별 데이터 리스트들
                for temp2 in temp1:  #temp2는 temp1의 리스트 하나
                    if temp2[2] == 'Connected':
                        connect.append(temp2[0] + ' ' + temp2[1] + ' ' +
                                       temp2[3] + ' ' + temp2[4])
                    elif temp2[2] == 'Disconnected':
                        disconnect.append(temp2[0] + ' ' + temp2[1] + ' ' +
                                          temp2[3] + ' ' + temp2[4])
                    else:
                        continue
                out_data["onhub_connect"] = connect
                out_data["onhub_disconnect"] = disconnect
            elif key[0:11] == 'Amazon Echo':
                temp1 = in_data[key]  # temp1은 각 기기별 데이터 리스트들
                for temp2 in temp1:  # temp2는 temp1의 리스트 하나
                    echo.append(temp2)
                out_data["amazon_echo"] = echo
            elif key[0:8] == 'Database':
                temp1 = in_data[key]  # temp1은 각 기기별 데이터 리스트들
                for temp2 in temp1:  # temp2는 temp1의 리스트 하나
                    database.append(temp2)
                out_data["Database"] = database

        ###View 함수로 이동

    def Read_Data(self, Filepath, time_list, index):
        global utc_timezone

        f = open(Filepath, 'r')

        data_a = csv.reader(f)
        count = 0
        list = []
        device_name = 0

        for data in data_a:
            if not data:
                pass
            else:
                if count == 0:
                    if data[0][0:5] == 'Onhub':
                        device_name = data[0].split('-')[0]
                    elif data[0][0:11] == 'Amazon Echo':
                        device_name = data[0].split('-')[0]
                    elif data[0][0:8] == 'Database':
                        device_name = data[0].split(
                            '_')[0] + '(' + data[0].split('(')[1].split('-')[0]
                    temp = QtCore.QString(data[1].split("UTC")[1])
                    if temp[0] == '-':
                        utc_timezone_temp = float(
                            temp[0:3]) - float(temp[4:6]) / 60
                    else:
                        utc_timezone_temp = float(
                            temp[0:3]) + float(temp[4:6]) / 60
                    utc_timezone_dic[device_name] = utc_timezone_temp
                    count = 1
                elif data[0].find('Time') >= 0:
                    count = 2
                elif count == 2:
                    if data[0] == '="None"':
                        pass
                    else:
                        data.append(
                            device_name)  # 기기정보 추가(날짜, 맥주소, 연결/연결해제, 기기정보)
                        data.append(str(index))
                        list.append(data)
                        if utc_timezone_dic[device_name] == utc_timezone:
                            time_list.append(data[0].split('"')[1].split('"')
                                             [0])  # time_list는 시간정보
                        else:
                            time_temp = data[0].split('"')[1].split('"')[0]
                            time_temp = self.convert_utc_timezone(
                                time_temp,
                                utc_timezone - utc_timezone_dic[device_name])
                            time_list.append(time_temp)  # time_list는 시간정보
        f.close()
        return list

    def init_view(self):
        plt.clf()
        plt.ylim(0, len(device_list))  # y축 최소,최대값 설정
        plt.yticks(np.arange(0, len(device_list)), device_list)  # y축 눈금
        plt.xlim(0, 24)  # x축 최소,최대값 설정
        plt.xticks(np.arange(0, 25))  # x축 눈금
        plt.xlabel('time(hours)')
        plt.ylabel('devices')
        plt.title('Result')

    def View(self):
        self.init_view()
        global utc_timezone
        sc_onhub_connect = []
        del sc_onhub_connect[:]
        sc_onhub_connect_index = []
        del sc_onhub_connect_index[:]
        sc_onhub_disconnect = []
        del sc_onhub_disconnect[:]
        sc_onhub_disconnect_index = []
        del sc_onhub_disconnect_index[:]
        onhub_disconnect_annot.clear
        onhub_connect_annot.clear
        sc_Database = []
        del sc_Database[:]
        sc_Database_index = []
        del sc_Database_index[:]
        Database_annot.clear
        sc_amazon_echo = []
        del sc_amazon_echo[:]
        sc_amazon_echo_index = []
        del sc_amazon_echo_index[:]
        echo_annot.clear

        if (out_data["onhub_connect"] is ''
            ) & (out_data["onhub_disconnect"] is '') & (
                out_data["Database"] is '') & (out_data["amazon_echo"] is ''):
            self.canvas.draw()
            self.clear_view()
        else:
            self.annot = plt.annotate("",
                                      xy=(0, 0),
                                      xytext=(20, 20),
                                      textcoords="offset points",
                                      bbox=dict(boxstyle="round", fc="w"),
                                      arrowprops=dict(arrowstyle="->"))
            if out_data["onhub_connect"]:
                sc_onhub_connect_temp = out_data["onhub_connect"]
                if utc_timezone_dic[sc_onhub_connect_temp[0].split(' ')
                                    [3]] == utc_timezone:
                    for i in range(len(sc_onhub_connect_temp)):
                        time = sc_onhub_connect_temp[i].split(' ')[0].split(
                            '"')[1]
                        if (Date["year"] == time.split('-')[0]) & (
                                Date["month"] == time.split('-')[1]) & (
                                    Date["day"] == time.split('-')[2]):
                            time2 = sc_onhub_connect_temp[i].split(
                                ' ')[1].split('"')[0]
                            add_data = float(time2.split(":")[0]) + (
                                float(time2.split(":")[1]) / 60) + (
                                    (float(time2.split(":")[2]) / 60) / 60
                                )  # X축 시간 계산  ##########split 데이터 수정
                            sc_onhub_connect.append(round(add_data, 4))
                            index = sc_onhub_connect_temp[i].split(' ')[4]
                            onhub_connect_annot[round(
                                add_data, 4
                            )] = index + '|' + 'MAC address : ' + sc_onhub_connect_temp[
                                i].split(' ')[2].split('"')[1].split(
                                    '"'
                                )[0] + '\n' + 'time : ' + sc_onhub_connect_temp[
                                    i].split(' ')[0].split(
                                        '"')[1] + ' ' + sc_onhub_connect_temp[
                                            i].split(' ')[1].split('"')[
                                                0] + '\n' + 'Action: Connected'
                            sc_onhub_connect_index.append(int(index))
                        else:
                            continue
                else:
                    gap = utc_timezone - utc_timezone_dic[
                        sc_onhub_connect_temp[0].split(' ')[3]]
                    for i in range(len(sc_onhub_connect_temp)):
                        time_temp = sc_onhub_connect_temp[i].split(
                            '"')[1].split('"')[0]
                        convert_time = self.convert_utc_timezone(
                            time_temp, gap)
                        time = convert_time.split(' ')[0]
                        if (Date["year"] == time.split('-')[0]) & (
                                Date["month"] == time.split('-')[1]) & (
                                    Date["day"] == time.split('-')[2]):
                            time2 = convert_time.split(' ')[1]
                            add_data = float(time2.split(":")[0]) + (
                                float(time2.split(":")[1]) / 60) + (
                                    (float(time2.split(":")[2]) / 60) / 60
                                )  # X축 시간 계산  ##########split 데이터 수정
                            sc_onhub_connect.append(round(add_data, 4))
                            index = sc_onhub_connect_temp[i].split(' ')[4]
                            onhub_connect_annot[round(
                                add_data, 4
                            )] = index + '|' + 'MAC address : ' + sc_onhub_connect_temp[
                                i].split(' ')[2].split('"')[1].split(
                                    '"'
                                )[0] + '\n' + 'time : ' + convert_time + '\n' + 'Action: Connected'
                            sc_onhub_connect_index.append(int(index))
                self.onhub_connect = plt.scatter(sc_onhub_connect,
                                                 sc_onhub_connect_index,
                                                 color='R',
                                                 edgecolors='R',
                                                 s=50,
                                                 label='Connected')
            else:
                self.onhub_connect = plt.scatter(sc_onhub_connect,
                                                 sc_onhub_connect_index,
                                                 color='R',
                                                 edgecolors='R',
                                                 s=50)

            if out_data["onhub_disconnect"]:
                sc_onhub_disconnect_temp = out_data["onhub_disconnect"]
                if utc_timezone_dic[sc_onhub_disconnect_temp[0].split(' ')
                                    [3]] == utc_timezone:
                    for i in range(len(sc_onhub_disconnect_temp)):
                        time = sc_onhub_disconnect_temp[i].split(' ')[0].split(
                            '"')[1]
                        if (Date["year"] == time.split('-')[0]) & (
                                Date["month"] == time.split('-')[1]) & (
                                    Date["day"] == time.split('-')[2]):
                            time2 = sc_onhub_disconnect_temp[i].split(
                                ' ')[1].split('"')[0]
                            add_data = float(time2.split(":")[0]) + (
                                float(time2.split(":")[1]) / 60) + (
                                    (float(time2.split(":")[2].split(".")[0]) /
                                     60) / 60)  # X축 시간 계산
                            sc_onhub_disconnect.append(round(add_data, 4))
                            index = sc_onhub_disconnect_temp[i].split(' ')[4]
                            sc_onhub_disconnect_index.append(int(index))
                            onhub_disconnect_annot[round(
                                add_data, 4
                            )] = index + '|' + 'MAC address : ' + sc_onhub_disconnect_temp[
                                i].split(' ')[2].split('"')[1].split(
                                    '"'
                                )[0] + '\n' + 'time : ' + sc_onhub_disconnect_temp[
                                    i].split(' ')[0].split(
                                        '"'
                                    )[1] + ' ' + sc_onhub_disconnect_temp[
                                        i].split(' ')[1].split('"')[
                                            0] + '\n' + 'Action: Disconnected'
                        else:
                            continue
                else:
                    gap = utc_timezone - utc_timezone_dic[
                        sc_onhub_disconnect_temp[0].split(' ')[3]]
                    for i in range(len(sc_onhub_disconnect_temp)):
                        time_temp = sc_onhub_disconnect_temp[i].split(
                            '"')[1].split('"')[0]
                        convert_time = self.convert_utc_timezone(
                            time_temp, gap)
                        time = convert_time.split(' ')[0]
                        if (Date["year"] == time.split('-')[0]) & (
                                Date["month"] == time.split('-')[1]) & (
                                    Date["day"] == time.split('-')[2]):
                            time2 = convert_time.split(' ')[1]
                            add_data = float(time2.split(":")[0]) + (
                                float(time2.split(":")[1]) / 60) + (
                                    (float(time2.split(":")[2].split(".")[0]) /
                                     60) / 60)  # X축 시간 계산
                            sc_onhub_disconnect.append(round(add_data, 4))
                            index = sc_onhub_disconnect_temp[i].split(' ')[4]
                            sc_onhub_disconnect_index.append(int(index))
                            onhub_disconnect_annot[round(
                                add_data, 4
                            )] = index + '|' + 'MAC address : ' + sc_onhub_disconnect_temp[
                                i].split(' ')[2].split('"')[1].split(
                                    '"'
                                )[0] + '\n' + 'time : ' + convert_time + '\n' + 'Action: Disconnected'
                self.onhub_disconnect = plt.scatter(sc_onhub_disconnect,
                                                    sc_onhub_disconnect_index,
                                                    marker='X',
                                                    color='k',
                                                    label='Disconnected')
            else:
                self.onhub_disconnect = plt.scatter(sc_onhub_disconnect,
                                                    sc_onhub_disconnect_index,
                                                    marker='X',
                                                    color='k')

            if out_data["amazon_echo"]:
                sc_amazon_echo_temp = out_data["amazon_echo"]
                if utc_timezone_dic[sc_amazon_echo_temp[0][3]] == utc_timezone:
                    for i in range(len(sc_amazon_echo_temp)):
                        time = sc_amazon_echo_temp[i][0].split('"')[1].split(
                            ' ')[0]
                        if (Date["year"] == time.split('-')[0]) & (
                                Date["month"] == time.split('-')[1]) & (
                                    Date["day"] == time.split('-')[2]):
                            time2 = sc_amazon_echo_temp[i][0].split(
                                ' ')[1].split('"')[0]
                            add_data = float(time2.split(":")[0]) + (
                                float(time2.split(":")[1]) / 60) + (
                                    (float(time2.split(":")[2].split(".")[0]) /
                                     60) / 60)  # X축 시간 계산
                            sc_amazon_echo.append(round(add_data, 4))
                            index = sc_amazon_echo_temp[i][4]
                            sc_amazon_echo_index.append(int(index))
                            echo_annot[round(
                                add_data, 4
                            )] = 'File name : ' + sc_amazon_echo_temp[i][
                                1] + '\n' + 'time : ' + sc_amazon_echo_temp[i][
                                    0].split('"')[1].split(
                                        '"'
                                    )[0] + '\n' + 'command : ' + sc_amazon_echo_temp[
                                        i][2]
                        else:
                            continue
                else:
                    gap = utc_timezone - utc_timezone_dic[
                        sc_amazon_echo_temp[0][3]]
                    for i in range(len(sc_amazon_echo_temp)):
                        time_temp = sc_amazon_echo_temp[i][0].split(
                            '"')[1].split('"')[0]
                        convert_time = self.convert_utc_timezone(
                            time_temp, gap)
                        time = convert_time.split(' ')[0]
                        if (Date["year"] == time.split('-')[0]) & (
                                Date["month"] == time.split('-')[1]) & (
                                    Date["day"] == time.split('-')[2]):
                            time2 = convert_time.split(' ')[1]
                            add_data = float(time2.split(":")[0]) + (
                                float(time2.split(":")[1]) / 60) + (
                                    (float(time2.split(":")[2].split(".")[0]) /
                                     60) / 60)  # X축 시간 계산
                            sc_amazon_echo.append(round(add_data, 4))
                            index = sc_amazon_echo_temp[i][4]
                            sc_amazon_echo_index.append(int(index))
                            echo_annot[round(
                                add_data, 4
                            )] = 'File name : ' + sc_amazon_echo_temp[i][
                                1] + '\n' + 'time : ' + convert_time + '\n' + 'command : ' + sc_amazon_echo_temp[
                                    i][2]
                self.amazon_echo = plt.scatter(sc_amazon_echo,
                                               sc_amazon_echo_index,
                                               marker='*',
                                               color='b',
                                               label='Command Event')
            else:
                self.amazon_echo = plt.scatter(sc_amazon_echo,
                                               sc_amazon_echo_index,
                                               marker='*',
                                               color='b')

            if out_data["Database"]:
                sc_Database_temp = out_data["Database"]
                if utc_timezone_dic[sc_Database_temp[0][2]] == utc_timezone:
                    for i in range(len(sc_Database_temp)):
                        time = sc_Database_temp[i][0].split('"')[1].split(
                            ' ')[0]
                        if (Date["year"] == time.split('-')[0]) & (
                                Date["month"] == time.split('-')[1]) & (
                                    Date["day"] == time.split('-')[2]):
                            time2 = sc_Database_temp[i][0].split(' ')[1].split(
                                '"')[0]
                            add_data = float(time2.split(":")[0]) + (
                                float(time2.split(":")[1]) / 60) + (
                                    (float(time2.split(":")[2].split(".")[0]) /
                                     60) / 60)  # X축 시간 계산
                            sc_Database.append(round(add_data, 4))
                            index = sc_Database_temp[i][3]
                            sc_Database_index.append(int(index))
                            Database_annot[round(
                                add_data,
                                4)] = 'File name : ' + sc_Database_temp[i][
                                    1] + '\n' + 'time : ' + sc_Database_temp[
                                        i][0].split('"')[1].split('"')[
                                            0] + '\n' + 'Action: File Modified'
                        else:
                            continue
                else:
                    gap = utc_timezone - utc_timezone_dic[sc_Database_temp[0]
                                                          [2]]
                    for i in range(len(sc_Database_temp)):
                        time_temp = sc_Database_temp[i][0].split('"')[1].split(
                            '"')[0]
                        convert_time = self.convert_utc_timezone(
                            time_temp, gap)
                        time = convert_time.split(' ')[0]
                        if (Date["year"] == time.split('-')[0]) & (
                                Date["month"] == time.split('-')[1]) & (
                                    Date["day"] == time.split('-')[2]):
                            time2 = convert_time.split(' ')[1]
                            add_data = float(time2.split(":")[0]) + (
                                float(time2.split(":")[1]) / 60) + (
                                    (float(time2.split(":")[2].split(".")[0]) /
                                     60) / 60)  # X축 시간 계산
                            sc_Database.append(round(add_data, 4))
                            index = sc_Database_temp[i][3]
                            sc_Database_index.append(int(index))
                            Database_annot[round(
                                add_data, 4
                            )] = 'File name : ' + sc_Database_temp[i][
                                1] + '\n' + 'time : ' + convert_time + '\n' + 'Action: File Modified'
                self.Database = plt.scatter(sc_Database,
                                            sc_Database_index,
                                            marker='<',
                                            color='g',
                                            label='File Modified')
            else:
                self.Database = plt.scatter(sc_Database,
                                            sc_Database_index,
                                            marker='<',
                                            color='g')

            plt.legend(loc='best')
            self.annot.set_visible(False)
            self.canvas.draw()
            self.canvas.mpl_connect("motion_notify_event", self.event)

    def event(self, event):
        if event.inaxes is not None:
            if self.onhub_connect.contains(event)[0] is True:
                onhub_connect_x, onhub_connect_index = self.onhub_connect.contains(
                    event)
                self.update_connect_onhub(onhub_connect_index)
                self.annot.set_visible(True)
                event.canvas.draw()
            elif self.onhub_disconnect.contains(event)[0] is True:
                onhub_disconnect_x, onhub_disconnect_index = self.onhub_disconnect.contains(
                    event)
                self.update_disconnect_onhub(onhub_disconnect_index)
                self.annot.set_visible(True)
                event.canvas.draw()
            elif self.amazon_echo.contains(event)[0] is True:
                amazon_echo_x, amazon_echo_index = self.amazon_echo.contains(
                    event)
                self.update_amazon_echo(amazon_echo_index)
                self.annot.set_visible(True)
                event.canvas.draw()
            elif self.Database.contains(event)[0] is True:
                Database_x, Database_index = self.Database.contains(event)
                self.updat_database(Database_index)
                self.annot.set_visible(True)
                event.canvas.draw()
            else:
                self.annot.set_visible(False)
                self.canvas.draw_idle()

    def updat_database(self, ind):
        pos = self.Database.get_offsets()[ind["ind"][0]]
        self.annot.xy = pos
        text = Database_annot[pos[0]]
        self.annot.set_text(text)

    def update_amazon_echo(self, ind):
        pos = self.amazon_echo.get_offsets()[ind["ind"][0]]
        self.annot.xy = pos
        text = echo_annot[pos[0]]
        self.annot.set_text(text)

    def update_connect_onhub(self, ind):
        pos = self.onhub_connect.get_offsets()[ind["ind"][0]]
        self.annot.xy = pos
        text = onhub_connect_annot[pos[0]]
        if int(text.split('|')[0]) == pos[1]:
            self.annot.set_text(text.split('|')[1])
        else:
            pass

    def update_disconnect_onhub(self, ind):
        pos = self.onhub_disconnect.get_offsets()[ind["ind"][0]]
        self.annot.xy = pos
        text = onhub_disconnect_annot[pos[0]]
        if int(text.split('|')[0]) == pos[1]:
            self.annot.set_text(text.split('|')[1])
        else:
            pass
Esempio n. 11
0
class PlotCanvasWithToolbar(PlotFigure, QWidget):
    def __init__(self, parent=None):
        PlotFigure.__init__(self)
        QWidget.__init__(self, parent)

        self.canvas = FigureCanvas(self.fig)
        self.canvas.mpl_connect('draw_event', self.on_draw)
        self.toolbar = NavigationToolbar(self.canvas, self)
        self.toolbar.pan()  # Pan by default

        vbox = QVBoxLayout(self)
        vbox.addWidget(self.canvas)
        vbox.addWidget(self.toolbar)
        self.setLayout(vbox)

    def setupLockButtons(self, layout):
        self.x_locked = QtWidgets.QPushButton(u"Lock X", self)
        self.x_locked.setCheckable(True)
        layout.addWidget(self.x_locked)
        self.x_locked.toggled.connect(self.x_locked_changed)
        self.x_limits = None

        self.y1_locked = QtWidgets.QPushButton(u"Lock Y1", self)
        self.y1_locked.setCheckable(True)
        layout.addWidget(self.y1_locked)
        self.y1_locked.toggled.connect(self.y1_locked_changed)
        self.y1_limits = None

        self.y2_locked = QtWidgets.QPushButton(u"Lock Y2", self)
        self.y2_locked.setCheckable(True)
        layout.addWidget(self.y2_locked)
        self.y2_locked.toggled.connect(self.y2_locked_changed)
        self.y2_limits = None

    def axesDialog(self):
        SimpleAxesDialog(self).exec_()

    def on_draw(self, event):
        pass

    def draw(self):
        self.canvas.toolbar.update(
        )  # drop history of Home, Forward and Back buttons in the navigation toolbar
        PlotFigure.draw(self, self.x_limits, self.y1_limits, self.y2_limits)
        self.canvas.draw()

    def _y_lock_changed(self, name, cbox, get_lim):
        if cbox.isChecked():
            cbox.setText(u"Lock {}".format(name))
            return get_lim()
        else:
            cbox.setText(u"Lock {}".format(name))
            return None

    def x_locked_changed(self, status):
        self.x_limits = self._y_lock_changed("X", self.x_locked,
                                             self.axes.get_xlim)

    def y1_locked_changed(self, status):
        self.y1_limits = self._y_lock_changed("Y1", self.y1_locked,
                                              self.axes.get_ylim)

    def y2_locked_changed(self, status):
        self.y2_limits = self._y_lock_changed("Y2", self.y2_locked,
                                              self.axes2.get_ylim)
Esempio n. 12
0
 def pan(self):
     if self._active != 'PAN':
         self.toogle_off_all_active()
     NavigationToolbar.pan(self)
Esempio n. 13
0
class Window(QtGui.QDialog):
    def __init__(self, parent=None):

        super(Window, self).__init__(parent)

        self.setAcceptDrops(True)
        self.figure = plt.figure()

        # --- Just for fun lets start with nice picture

        img = mpimg.imread('./bq_t4_sys/thor.png')
        ax = plt.Axes(self.figure,[0.,0.,1.,1.])
        ax.set_axis_off()
        self.figure.add_axes(ax)
        plt.imshow(img,cmap=cm.get_cmap('gray'))

        # ---------------------------------------------

        self.canvas = FigureCanvas(self.figure)

        # ---------------------------------------------

        self.toolbar = NavigationToolbar(self.canvas, self)

        # ---------------------------------------------

        self.slider = QtGui.QSlider(orientation=Qt.Qt.Horizontal)
        self.slider.setTickInterval(1)
        self.slider.valueChanged.connect(self.plot)

        # ----------------------------------------------
        
        self.view_combo = QtGui.QComboBox(self)
        self.view_combo.activated[str].connect(self.changeView)
        self.view_combo.addItem('X-Y')
        self.view_combo.addItem('X-Z')
        self.view_combo.addItem('Y-Z')
        self.view = 'X-Y'
        self.slide_dimension = 2 # will slide by default though z

        self.combo = QtGui.QComboBox(self)
        self.combo.activated[str].connect(self.comboActivated)

        # -- check box 

        self.hbox = QtGui.QHBoxLayout()
        # self.hbox.addStretch(1)

        self.back_button = QtGui.QPushButton('<',self)
        self.back_button.clicked.connect(self.goBack)
        self.next_button = QtGui.QPushButton('>',self)
        self.next_button.clicked.connect(self.goNext)

        self.check_abs = QtGui.QCheckBox('Absolute')
        # self.check_abs.toggle()
        self.check_abs.stateChanged.connect(self.plot)

        self.check_bw = QtGui.QCheckBox('B&W')
        # self.check_bw.toggle()
        self.check_bw.stateChanged.connect(self.plot)

        self.check_log = QtGui.QCheckBox('Log')
        # self.check_log.toggle()
        self.check_log.stateChanged.connect(self.plot)


        self.check_si = QtGui.QCheckBox('CGS Units')
        self.check_si.toggle()
        self.check_si.stateChanged.connect(self.plot)

        self.check_aux = QtGui.QCheckBox('No AUX')
        self.check_aux.toggle()
        self.check_aux.stateChanged.connect(self.reset_bifrost_obj)

        self.hbox.addWidget(self.check_si)
        self.hbox.addWidget(self.check_abs)
        self.hbox.addWidget(self.check_log)
        self.hbox.addWidget(self.check_bw)
        self.hbox.addWidget(self.check_aux)
        self.hbox.addWidget(self.back_button)
        self.hbox.addWidget(self.next_button)
        self.hbox.addWidget(self.combo)
        self.hbox.addWidget(self.view_combo)

        # set the layout
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.toolbar)
        layout.addLayout(self.hbox)
        layout.addWidget(self.canvas)
        layout.addWidget(self.slider)
        self.setLayout(layout)

        # actual data stuff
        self.fpath = first_file_name

        # self.data = np.einsum('ijk->kji', self.data)

        self.tag = 'r'

        if (first_file_name != "no_file"):
            self.param = get_bifrost_param(self.fpath,0)
            self.b, self.base_name, self.snap_n = get_bifrost_obj(self.fpath,0, self.check_aux.isChecked())
            self.data = self.b.getvar(self.tag)
            self.slide_dimension = 2
            self.slider.setMinimum(0)
            self.slider.setMaximum(self.data.shape[self.slide_dimension]-1)

            if (first_slice != -1):
                self.slider.setValue(first_slice)

            if (first_depth != -1000.0):
                self.slider.setValue(np.argmax( self.b.z >= first_depth ))

            if self.slider.value() >= self.data.shape[self.slide_dimension]:
                self.slider.setValue(self.data.shape[self.slide_dimension]-1)
            elif self.slider.value() < 0:
                self.slider.setValue(0)

            self.setCombo()
            self.plot()
        else:
            print "\t[!] Drag & Drop a snap file to plot its content"


    def keyPressEvent(self, event):
        
        key = event.key

        if key == Qt.Qt.Key_Right:
            self.slider.setValue(self.slider.value() + 1)
        elif key == Qt.Qt.Key_Left:
            self.slider.setValue(self.slider.value() - 1)

    def goBack(self):
        self.param = get_bifrost_param(self.fpath,-1)
        self.b, self.base_name, self.snap_n = get_bifrost_obj(self.fpath,-1, self.check_aux.isChecked())
        self.get_data()
        self.plot()
        where_str, base_name, snap_n = process_file_name(self.fpath)
        snap_n = str(int(snap_n) - 1)
        self.fpath = where_str + base_name + '_' + snap_n + '.snap'
        pass

    def goNext(self):
        self.param = get_bifrost_param(self.fpath,1)
        self.b, self.base_name, self.snap_n = get_bifrost_obj(self.fpath,1,self.check_aux.isChecked())
        self.get_data()
        self.plot()
        where_str, base_name, snap_n = process_file_name(self.fpath)
        snap_n = str(int(snap_n) + 1)
        self.fpath = where_str + base_name + '_' + snap_n + '.snap'
        pass

    def setCombo(self):
        self.combo.clear()
        for tag in self.b.snapvars:
            self.combo.addItem(tag)
        if not self.check_aux.isChecked():
            for tag in self.b.auxvars:
                self.combo.addItem(tag)
    
    def changeView(self, text):
        self.view = text
        self.get_data()
        self.plot()
        print 'View changed to: ', self.view

    def comboActivated(self, text):
        self.tag = text
        self.data = self.b.getvar(self.tag)
        self.plot()

    def reset_bifrost_obj(self):
        self.b, self.base_name, self.snap_n = get_bifrost_obj(self.fpath,0,self.check_aux.isChecked())
        print self.b.snapvars
        self.get_data()

    def get_data(self):
        self.data = self.b.getvar(self.tag)
        if self.view == 'X-Y':
            self.slide_dimension = 2
        elif self.view == 'X-Z':
            self.slide_dimension = 1
        elif self.view == 'Y-Z':
            self.slide_dimension = 0

        self.slider.setMinimum(0)
        self.slider.setMaximum(self.data.shape[self.slide_dimension]-1)

        if self.slider.value() >= self.data.shape[self.slide_dimension]:
            self.slider.setValue(self.data.shape[self.slide_dimension]-1)
        elif self.slider.value() < 0:
            self.slider.setValue(0)

        self.setCombo()

    def home(self):
        self.toolbar.home()
    def zoom(self):
        self.toolbar.zoom()
    def pan(self):
        self.toolbar.pan()

    def plot(self):
        plt.clf()
        ax = self.figure.add_subplot(111)
        slice_str = '[?]'
        # extension = []
        if self.view == 'X-Y':
            image = self.data[:,:,self.slider.value()]
            slice_str = 'z = %f ' % self.b.z[self.slider.value()]
            ax.set_ylabel('y-direction')
            ax.set_xlabel('x-direction')
            # extension = [0, self.param['mx'], 0, self.param['my']]
        elif self.view == 'X-Z':
            image = self.data[:,self.slider.value(),:]
            slice_str = 'y = %f ' % self.b.y[self.slider.value()]
            ax.set_ylabel('z-direction')
            ax.set_xlabel('x-direction')
            # extension = [0, self.param['mx'], 0, self.param['mz']]
        elif self.view == 'Y-Z':
            image = self.data[self.slider.value(),:,:]
            slice_str = 'x = %f ' % self.b.x[self.slider.value()]
            ax.set_ylabel('z-direction')
            ax.set_xlabel('y-direction')
            # extension = [0, self.param['my'], 0, self.param['mz']]
        # image = np.fliplr(image)
        # image = np.rot90(image,k=3)
        
        label = "Value"
        color = cm.get_cmap('jet')
        
        ax.set_title("[%s] %s (Snap: %s) for %s \n[time: %s]" % (self.tag, self.base_name, self.snap_n, slice_str, str(datetime.timedelta(seconds=self.param['t']*self.param['u_t']))))
        # ax.xaxis.set_major_locator(ticker.MultipleLocator(int(64)))
        # ax.yaxis.set_major_locator(ticker.MultipleLocator(int(64)))
        
        if self.check_si.isChecked():
            
            if self.tag == 'r':
                image = image * self.param['u_r']
                unit_label = "[g/cm3]"
                label = "Value %s" % unit_label
            elif (self.tag == 'bx' or self.tag == 'by' or self.tag == 'bz'):
                image = image * self.param['u_b']
                unit_label = "[G]"
                label = "Value %s" % unit_label
            elif (self.tag == 'px' or self.tag == 'py' or self.tag == 'pz'):
                image = image * self.param['u_p']
                unit_label = "[Ba]"
                label = "Value %s" % unit_label
            elif self.tag == 'e':
                image = image * self.param['u_e']
                unit_label = "[erg]"
                label = "Value %s" % unit_label

        if self.check_abs.isChecked():
            image = np.absolute(image)
            label = "ABS( %s )" % label
        
        if self.check_log.isChecked():
            image = np.log10(image)
            label = "Log10( %s )" % label
        if self.check_bw.isChecked():
            # color = cm.get_cmap('gist_yarg')
            color = cm.get_cmap('Greys_r') # Mats favorite color palette 
            
        if self.view == 'X-Y':
            ax.set_ylabel('y-direction [Mm]')
            ax.set_xlabel('x-direction [Mm]')
            im = NonUniformImage(ax, interpolation='bilinear', extent=(self.b.x.min(),self.b.x.max(),self.b.y.min(),self.b.y.max()), cmap=color)
            im.set_data(self.b.x, self.b.y, np.fliplr(zip(*image[::-1])))
            ax.images.append(im)
            ax.set_xlim(self.b.x.min(),self.b.x.max())
            ax.set_ylim(self.b.y.min(),self.b.y.max())
            ax.xaxis.set_major_locator(ticker.MultipleLocator(int(4)))
            ax.yaxis.set_major_locator(ticker.MultipleLocator(int(4)))
        elif self.view == 'X-Z':
            ax.set_ylabel('z-direction [Mm]')
            ax.set_xlabel('x-direction [Mm]')
            im = NonUniformImage(ax, interpolation='bilinear', extent=(self.b.x.min(),self.b.x.max(),self.b.z.min(),self.b.z.max()), cmap=color)
            im.set_data(self.b.x, self.b.z[::-1], np.flipud(np.fliplr(zip(*image[::-1]))))
            ax.images.append(im)
            ax.set_xlim(self.b.x.min(),self.b.x.max())
            ax.set_ylim(self.b.z.max(),self.b.z.min())
            ax.xaxis.set_major_locator(ticker.MultipleLocator(int(4)))
            ax.yaxis.set_major_locator(ticker.MultipleLocator(int(2)))
        elif self.view == 'Y-Z':
            ax.set_ylabel('z-direction [Mm]')
            ax.set_xlabel('y-direction [Mm]')
            im = NonUniformImage(ax, interpolation='bilinear', extent=(self.b.y.min(),self.b.y.max(),self.b.z.min(),self.b.z.max()), cmap=color)
            im.set_data(self.b.y, self.b.z[::-1], np.flipud(np.fliplr(zip(*image[::-1]))))
            ax.images.append(im)
            ax.set_xlim(self.b.y.min(),self.b.y.max())
            ax.set_ylim(self.b.z.max(),self.b.z.min())
            ax.xaxis.set_major_locator(ticker.MultipleLocator(int(4)))
            ax.yaxis.set_major_locator(ticker.MultipleLocator(int(2)))
        # im = ax.imshow(image, interpolation='none', origin='lower', cmap=color, extent=extension)
        # ax.text(0.025, 0.025, (r'$\langle  B_{z}  \rangle = %2.2e$'+'\n'+r'$\langle |B_{z}| \rangle = %2.2e$') % (np.average(img),np.average(np.absolute(img))), ha='left', va='bottom', transform=ax.transAxes)
        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        plt.colorbar(im, cax=cax,label=label)
        self.canvas.draw()

    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.accept()
        else:
            event.ignore()

    def dropEvent(self, event):
        for url in event.mimeData().urls():
            path = url.toLocalFile().toLocal8Bit().data()
        if os.path.isfile(path):
            self.fpath = path
            self.param = get_bifrost_param(self.fpath,0)
            self.b, self.base_name, self.snap_n = get_bifrost_obj(self.fpath,0, self.check_aux.isChecked())
            self.get_data()
            self.plot()
Esempio n. 14
0
 def pan(self):
     NavigationToolbar.pan(self)
     self.mode = ""  #<--- whatever you want to replace "pan/zoom" goes here
     self.set_message(self.mode)
Esempio n. 15
0
class MainWindow(QtGui.QMainWindow, mw.Ui_MainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setupUi(self)
        self.datalst = []
        self.modellst = []
        self.lstdatamodel = QtGui.QStandardItemModel(self.listView)
        self.listView.setModel(self.lstdatamodel)
        self.current_lst_index = -1
        self.addButton.clicked.connect(self.add)
        self.removeButton.clicked.connect(self.remove)
        self.actionCalcLSSParameter.triggered.connect(self.calculatelss)
        self.actionAutomaticElutionWindowStretching.triggered.connect(self.calcautelwindowstretch)
        self.actionSelectivityMap.triggered.connect(self.pltselectivitymap)
        self.actionResolutionMap.triggered.connect(self.pltresolutionmap)
        self.actionAbout.triggered.connect(self.about)
        self.actionQuit.triggered.connect(self.quit)
        self.listView.clicked.connect(self.viewmatrix)
        self.toolBox.currentChanged.connect(self.viewmatrix)

        self.zoomButton.clicked.connect(self.zoom)
        self.panButton.clicked.connect(self.pan)
        self.rescaleButton.clicked.connect(self.home)
        self.modelBox.currentIndexChanged.connect(self.gradientanalyser)
        self.doubleSpinBox_1.valueChanged.connect(self.gradientanalyser)
        self.doubleSpinBox_2.valueChanged.connect(self.gradientanalyser)
        self.doubleSpinBox_3.valueChanged.connect(self.gradientanalyser)
        self.doubleSpinBox_4.valueChanged.connect(self.gradientanalyser)
        self.doubleSpinBox_5.valueChanged.connect(self.gradientanalyser)
        self.ColumnLenghtSpinBox.valueChanged.connect(self.gradientanalyser)
        self.CulumnDiameterSpinBox.valueChanged.connect(self.gradientanalyser)
        self.ColumnPorositySpinBox.valueChanged.connect(self.gradientanalyser)

        # Add plot
        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure)
        self.toolbar = NavigationToolbar(self.canvas, self)
        self.toolbar.hide()

        # set the layout
        layout_chormatogram = QtGui.QVBoxLayout()
        layout_chormatogram.addWidget(self.canvas)
        self.plotterBox.setLayout(layout_chormatogram)

        # Add selectivity map plot
        #self.figure_smap = plt.figure()
        #self.canvas_smap = FigureCanvas(self.figure_smap)
        #self.toolbar_smap = NavigationToolbar(self.canvas_smap, self)
        #self.toolbar_smap.hide()

        #layout_smap = QtGui.QVBoxLayout()
        #layout_smap.addWidget(self.canvas_smap)
        #self.plotterBox_2.setLayout(layout_smap)

        self.tablemodel = TableModel(self)
        self.tableView.setModel(self.tablemodel)
        self.tableView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.tableView.customContextMenuRequested.connect(self.openTableMenu)

        # constant parameters
        self.crit_resolution = 1.8
        self.crit_alpha = 1.1

    def openTableMenu(self, position):
        """ context menu event """
        menu = QtGui.QMenu(self)
        exportAction = menu.addAction("Export table as CSV")
        action = menu.exec_(self.tableView.viewport().mapToGlobal(position))

        if action == exportAction:
            fname = QtGui.QFileDialog.getSaveFileName(self, "Save File", "CSV (*.csv)");
            #fname = QtGui.getSaveFileName.getOpenFileName(self, tr('Save File'), )
            self.tablemodel.SaveTable(fname)
        else:
            return


        return


    def keyPressEvent(self, e):
        if (e.modifiers() & QtCore.Qt.ControlModifier):
            if e.key() == QtCore.Qt.Key_C: #copy
                if len(self.tableView.selectionModel().selectedIndexes()) > 0:
                    previous = self.tableView.selectionModel().selectedIndexes()[0]
                    columns = []
                    rows = []
                    for index in self.tableView.selectionModel().selectedIndexes():
                        if previous.column() != index.column():
                            columns.append(rows)
                            rows = []
                        rows.append(str(index.data().toPyObject()))
                        previous = index
                    columns.append(rows)

                    # add rows and columns to clipboard
                    clipboard = ""
                    nrows = len(columns[0])
                    ncols = len(columns)
                    for r in xrange(nrows):
                        for c in xrange(ncols):
                            clipboard += columns[c][r]
                            if c != (ncols-1):
                                clipboard += '\t'
                        clipboard += '\n'

                    # copy to the system clipboard
                    sys_clip = QtGui.QApplication.clipboard()
                    sys_clip.setText(clipboard)

    def home(self):
        self.toolbar.home()
    def zoom(self):
        self.toolbar.zoom()
    def pan(self):
        self.toolbar.pan()

    def plotchromatogram(self):
        ''' plot some random stuff '''
        data = [random.random() for i in range(25)]
        ax = self.figure.add_subplot(111)
        ax.hold(False)
        ax.plot(data, '*-')
        self.canvas.draw()

    def add(self):
        idialog = ImportDialog()
        if idialog.exec_() == 1:
            [name, molname, trdata, grad, tg, td, t0, flow, c_length, c_diameter, c_particle] = idialog.getdata()
            self.datalst.append(Data(name, molname, trdata, grad, tg, td, t0, flow, c_length, c_diameter, c_particle))
            self.lstdatamodel.appendRow(QtGui.QStandardItem(name))

    def remove(self):
        if self.current_lst_index >= 0 and self.current_lst_index < len(self.datalst):
            del self.datalst[self.current_lst_index]
            self.lstdatamodel.removeRow(self.current_lst_index)

    def viewmatrix(self, indx):
        if self.toolBox.currentIndex() == 0:
            if indx:
                self.current_lst_index =  indx.row()
                del self.tablemodel.arraydata[:]
                del self.tablemodel.header[:]
                self.tablemodel.clean()
                self.tableView.model().layoutChanged.emit()
                molname = self.datalst[self.current_lst_index].molname
                trdata = self.datalst[self.current_lst_index].trdata
                grad = self.datalst[self.current_lst_index].grad
                tg = self.datalst[self.current_lst_index].tg
                header = ["Molecule"]
                for j in range(len(tg)):
                    header.append(str("%.1f%% %.1f%% %.1f min" % (round(grad[j][0]*100,1), round(grad[j][1]*100,1), tg[j])))
                self.tablemodel.setHeader(header)
                for i in range(len(trdata)):
                    row = [molname[i]]
                    for j in range(len(trdata[i])):
                        row.append(round(trdata[i][j], 2))
                    self.tablemodel.addRow(row)
                self.tableView.model().layoutChanged.emit()
        else:
            del self.tablemodel.arraydata[:]
            del self.tablemodel.header[:]
            self.tablemodel.clean()
            self.tableView.model().layoutChanged.emit()
            self.gradientanalyser()

    def about(self):
        adialog = AboutDialog()
        adialog.exec_()

    def quit(self):
        QtGui.QApplication.quit()

    def calculatelss(self):
        items = []
        lstmodel = self.listView.model()
        for index in range(lstmodel.rowCount()):
            item = lstmodel.item(index)
            items.append(item.text())

        runlss = ComputeLSS(items)
        if runlss.exec_() == 1:
            [indx, modelname] = runlss.getdata()
            t0 = self.datalst[indx].t0
            v_d = self.datalst[indx].vd
            flow = self.datalst[indx].flow

            lssmol = SSGenerator(None, None, None, t0, v_d, flow)

            self.modellst.append(Model())
            self.modellst[-1].modname = modelname
            self.modellst[-1].molname = self.datalst[indx].molname
            self.modellst[-1].flow = self.datalst[indx].flow
            self.modellst[-1].c_length = self.datalst[indx].c_length
            self.modellst[-1].c_diameter = self.datalst[indx].c_diameter
            self.modellst[-1].c_particle = self.datalst[indx].c_particle
            self.modelBox.addItem(modelname)

            tg = self.datalst[indx].tg
            init_B = []
            final_B = []
            for i in range(len(tg)):
                init_B.append(self.datalst[indx].grad[i][0])
                final_B.append(self.datalst[indx].grad[i][1])

            self.modellst[-1].v_d = v_d
            self.modellst[-1].v_m = t0 * flow

            for row in self.datalst[indx].trdata:
                lss_logkw, lss_s = lssmol.getlssparameters(row, tg, init_B, final_B)
                self.modellst[-1].lss.append([lss_logkw, lss_s])

            if len(self.modellst) == 1:
                self.gradientanalyser()

    def calcautelwindowstretch(self):
        aws = AutomaticElutionWindowStretching(self.modellst)
        aws.exec_()

    def pltselectivitymap(self):
        smap = PlotMaps(self.modellst, "sel")
        smap.exec_()

    def pltresolutionmap(self):
        rsmap = PlotMaps(self.modellst, "res")
        rsmap.exec_()

    def gradientanalyser(self):
        indx = self.modelBox.currentIndex()
        del self.tablemodel.arraydata[:]
        del self.tablemodel.header[:]
        self.tablemodel.clean()
        header = ["Molecule", "log kW", "S", "tR"]
        self.tablemodel.setHeader(header)
        self.tableView.model().layoutChanged.emit()
        if indx >= 0 and indx < len(self.modellst):
            #predict the retention time for each compound
            molname = [name for name in self.modellst[indx].molname]
            lss = self.modellst[indx].lss
            flow_sofware = float(self.doubleSpinBox_1.value())
            init_B_soft = float(self.doubleSpinBox_2.value())/100.
            final_B_soft = float(self.doubleSpinBox_3.value())/100.
            tg_soft = float(self.doubleSpinBox_4.value())

            c_length = self.ColumnLenghtSpinBox.value()
            c_diameter = self.CulumnDiameterSpinBox.value()
            c_particle = self.ColumnPorositySpinBox.value()

            t0_soft = 0.
            td_soft = 0.

            v_m = None
            v_d = float(self.doubleSpinBox_5.value())

            #if c_length > 0 and c_diameter > 0 and c_porosity > 0:
            #    v_m = ((square(self.c_diameter)*self.c_length*pi*self.c_porosity)/4.)/1000.
            #else:
            v_m = self.modellst[indx].v_m

            t0_soft = float(v_m/flow_sofware)
            td_soft = float(v_d/flow_sofware)

            A = 1.0

            #N = (c_length*10000.)/(3.4*c_particle)
            trtab = []
            lssmol = SSGenerator(None, None, None, t0_soft, float(self.modellst[indx].v_d), flow_sofware)
            i = 0
            trlst = []
            for row in lss:
                lss_logkw = float(row[0])
                lss_s = float(row[1])
                W = get_lss_peak_width(c_length, c_particle, lss_logkw, lss_s, init_B_soft, final_B_soft, tg_soft, flow_sofware, self.modellst[indx].v_m, self.modellst[indx].v_d, None)
                tr = lssmol.rtpred(lss_logkw, lss_s, tg_soft, init_B_soft, final_B_soft, t0_soft, td_soft)
                if tr < t0_soft:
                    trtab.append([t0_soft, A, W])
                else:
                    trtab.append([tr, A, W])
                trlst.append([round(trtab[-1][0], 2), W, molname[i]])
                row = [molname[i], round(lss_logkw, 3), round(lss_s, 3), round(trtab[-1][0],2)]
                self.tablemodel.addRow(row)
                self.tableView.model().layoutChanged.emit()
                i += 1

            # Calculate the critical resolution
            trlst = sorted(trlst, key=lambda x:x[0])
            # get min and max time
            tr_min = tr_max = 0.
            if len(trlst) > 0:
                tr_min = trlst[0][0]
                tr_max = trlst[-1][0]
                # calculate resolution and critical couple
                # get the peak width at base multiplying by 1.7
                self.plainTextEdit.clear()
                text = "Critical couples:\n"
                self.plainTextEdit.appendPlainText(text)

                crit_trtab = []
                crit_molname = []
                ncc = 0
                for i in range(1, len(trlst)):
                    width1 = trlst[i][1] * 1.7
                    width2 = trlst[i-1][1] * 1.7
                    tr1 = trlst[i-1][0]
                    tr2 = trlst[i][0]
                    tmp_rs = (2*(tr2-tr1)) / (width1+width2)
                    if tmp_rs < self.crit_resolution:
                        molname_a = trlst[i-1][2]
                        molname_b = trlst[i][2]
                        text =  "  - %s  %.2f min\n" % (molname_a, round(trlst[i-1][0], 2))
                        text += "  - %s  %.2f min\n" % (molname_b, round(trlst[i][0], 2))
                        text += "Rs: %.2f\n" % round(tmp_rs, 2)
                        text += "#"*20
                        text += "\n"
                        self.plainTextEdit.appendPlainText(text)
                        ncc += 1
                        if molname_a not in crit_molname:
                            # add to critical tr tab
                            a_indx = molname.index(molname_a)
                            crit_trtab.append(trtab.pop(a_indx))
                            crit_molname.append(molname.pop(a_indx))

                        if molname_b not in crit_molname:
                            b_indx = molname.index(molname_b)
                            crit_trtab.append(trtab.pop(b_indx))
                            crit_molname.append(molname.pop(b_indx))
                    else:
                        continue

                self.plainTextEdit.appendPlainText("Total critical couples: %d" % (ncc))

                #Create a cromatogram
                peaks = BuildChromatogram(trtab, tg_soft, 0.01)
                peaks = zip(*peaks)

                crit_peaks = BuildChromatogram(crit_trtab, tg_soft, 0.01)
                crit_peaks = zip(*crit_peaks)

                y = []
                x = []
                for i in range(len(peaks)):
                    x.append(peaks[i][0])
                    y.append(0.)
                    len(peaks[0])
                    for j in range(1, len(peaks[0])):
                        y[-1] += peaks[i][j]

                crit_y = []
                crit_x = []
                for i in range(len(crit_peaks)):
                    crit_x.append(crit_peaks[i][0])
                    crit_y.append(0.)
                    len(peaks[0])
                    for j in range(1, len(crit_peaks[0])):
                        crit_y[-1] += crit_peaks[i][j]
                ax = self.figure.add_subplot(111)
                ax.hold(False)
                ax.plot(x, y, "b", crit_x, crit_y, "r")

                #ax.plot(x, y, '-', color='blue')
                #ax.plot(crit_x, crit_y, '-', color='red')
                plt.xlabel('Time')
                plt.ylabel('Signal')
                plt.xlim([tr_min-((tr_min*10.)/100.), tr_max+((tr_max*10.)/100.)])
                self.canvas.draw()
Esempio n. 16
0
class calibrlogger(PyQt4.QtGui.QMainWindow, Calibr_Ui_Dialog): # An instance of the class Calibr_Ui_Dialog is created same time as instance of calibrlogger is created

    def __init__(self, parent, settingsdict1={}, obsid=''):
        PyQt4.QtGui.QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))#show the user this may take a long time...
        self.obsid = obsid
        self.log_pos = None
        self.y_pos = None
        self.meas_ts = None
        self.head_ts = None
        self.level_masl_ts = None
        self.loggerpos_masl_or_offset_state = 1

        self.settingsdict = settingsdict1
        PyQt4.QtGui.QDialog.__init__(self, parent)        
        self.setAttribute(PyQt4.QtCore.Qt.WA_DeleteOnClose)
        self.setupUi(self) # Required by Qt4 to initialize the UI
        self.setWindowTitle("Calculate water level from logger") # Set the title for the dialog
        self.INFO.setText("Select the observation point with logger data to be adjusted.")
        self.log_calc_manual.setText("<a href=\"https://github.com/jkall/qgis-midvatten-plugin/wiki/4.-Edit-data\">Midvatten manual</a>")
      
        # Create a plot window with one single subplot
        self.calibrplotfigure = plt.figure() 
        self.axes = self.calibrplotfigure.add_subplot( 111 )
        self.canvas = FigureCanvas( self.calibrplotfigure )
        self.mpltoolbar = NavigationToolbar( self.canvas, self.widgetPlot )
        lstActions = self.mpltoolbar.actions()
        self.mpltoolbar.removeAction( lstActions[ 7 ] )
        self.layoutplot.addWidget( self.canvas )
        self.layoutplot.addWidget( self.mpltoolbar )
        self.calibrplotfigure.tight_layout()
        self.show()

        self.cid =[]
                
        self.connect(self.pushButtonSet, PyQt4.QtCore.SIGNAL("clicked()"), self.set_logger_pos)
        self.connect(self.pushButtonAdd, PyQt4.QtCore.SIGNAL("clicked()"), self.add_to_level_masl)
        self.connect(self.pushButtonFrom, PyQt4.QtCore.SIGNAL("clicked()"), self.set_from_date_from_x)
        self.connect(self.pushButtonTo, PyQt4.QtCore.SIGNAL("clicked()"), self.set_to_date_from_x)
        self.connect(self.pushButtonupdateplot, PyQt4.QtCore.SIGNAL("clicked()"), self.update_plot)
        #self.connect(self.loggerpos_masl_or_offset, PyQt4.QtCore.SIGNAL("clicked()"), self.loggerpos_masl_or_offset_change)
        #self.connect(self.pushButtonLpos, PyQt4.QtCore.SIGNAL("clicked()"), self.calibrate_from_plot_selection)
        self.connect(self.pushButtonLpos, PyQt4.QtCore.SIGNAL("clicked()"), self.catch_old_level)
        self.connect(self.pushButtonMpos, PyQt4.QtCore.SIGNAL("clicked()"), self.catch_new_level)
        self.pushButtonMpos.setEnabled(False)
        self.connect(self.pushButtonCalcBestFit, PyQt4.QtCore.SIGNAL("clicked()"), self.logger_pos_best_fit)
        self.connect(self.pushButtonCalcBestFit2, PyQt4.QtCore.SIGNAL("clicked()"), self.level_masl_best_fit)

        self.connect(self.pushButton_delete_logger, PyQt4.QtCore.SIGNAL("clicked()"), lambda: self.delete_selected_range(u'w_levels_logger'))

        self.get_search_radius()

        # Populate combobox with obsid from table w_levels_logger
        self.load_obsid_from_db()

        PyQt4.QtGui.QApplication.restoreOverrideCursor()#now this long process is done and the cursor is back as normal

    def load_obsid_from_db(self):
        print ('am here')#debug
        self.combobox_obsid.clear()
        myconnection = utils.dbconnection()
        if myconnection.connect2db() == True:
            print('connected')#debug
            # skapa en cursor
            curs = myconnection.conn.cursor()
            rs=curs.execute("""select distinct obsid from w_levels_logger order by obsid""")
            self.combobox_obsid.addItem('')
            for row in curs:
                print(row[0])#debug
                self.combobox_obsid.addItem(row[0])
            rs.close()
            myconnection.closedb()

    def load_obsid_and_init(self):
        """ Checks the current obsid and reloads all ts.
        :return: obsid

        Info: Before, some time series was only reloaded when the obsid was changed, but this caused a problem if the
        data was changed in the background in for example spatialite gui. Now all time series are reloaded always.
        It's rather fast anyway.
        """
        obsid = unicode(self.combobox_obsid.currentText())
        if not obsid:
            utils.pop_up_info("ERROR: no obsid is chosen")
            return None

        meas_sql = r"""SELECT date_time, level_masl FROM w_levels WHERE obsid = '""" + obsid + """' ORDER BY date_time"""
        self.meas_ts = self.sql_into_recarray(meas_sql)
        head_sql = r"""SELECT date_time as 'date [datetime]', head_cm / 100 FROM w_levels_logger WHERE obsid = '""" + obsid + """' ORDER BY date_time"""
        self.head_ts = self.sql_into_recarray(head_sql)
        self.obsid = obsid
        level_masl_ts_sql = r"""SELECT date_time as 'date [datetime]', level_masl FROM w_levels_logger WHERE obsid = '""" + self.obsid + """' ORDER BY date_time"""
        self.level_masl_ts = self.sql_into_recarray(level_masl_ts_sql)
        return obsid

    def getlastcalibration(self):
        obsid = self.load_obsid_and_init()
        if not obsid=='':
            sql = """SELECT MAX(date_time), loggerpos FROM (SELECT date_time, (level_masl - (head_cm/100)) as loggerpos FROM w_levels_logger WHERE level_masl > -990 AND obsid = '"""
            sql += obsid
            sql += """')"""
            self.lastcalibr = utils.sql_load_fr_db(sql)[1]
            if self.lastcalibr[0][1] and self.lastcalibr[0][0]:
                text = """Last pos. for logger in """
                text += obsid
                text += """ was """ + str(self.lastcalibr[0][1]) + """ masl at """ +  str(self.lastcalibr[0][0])
            else:
                text = """There is no earlier known position for the logger in """ + unicode(self.combobox_obsid.currentText())#self.obsid[0]
            self.INFO.setText(text)

    def set_logger_pos(self):
        self.loggerpos_masl_or_offset_state = 1
        obsid = self.load_obsid_and_init()
        if not self.LoggerPos.text() == '':
            self.calibrate()
        self.update_plot()

    def add_to_level_masl(self):
        self.loggerpos_masl_or_offset_state = 0
        obsid = self.load_obsid_and_init()
        if not self.Add2Levelmasl.text() == '':
            self.calibrate()
        self.update_plot()

    def calibrate(self):
        self.calib_help.setText("Calibrating")
        PyQt4.QtGui.QApplication.setOverrideCursor(PyQt4.QtCore.Qt.WaitCursor)
        obsid = self.load_obsid_and_init()
        if not obsid=='':        
            sanity1sql = """select count(obsid) from w_levels_logger where obsid = '""" +  obsid[0] + """'"""
            sanity2sql = """select count(obsid) from w_levels_logger where head_cm not null and head_cm !='' and obsid = '""" +  obsid[0] + """'"""
            if utils.sql_load_fr_db(sanity1sql)[1] == utils.sql_load_fr_db(sanity2sql)[1]: # This must only be done if head_cm exists for all data
                fr_d_t = self.FromDateTime.dateTime().toPyDateTime()
                to_d_t = self.ToDateTime.dateTime().toPyDateTime()

                if self.loggerpos_masl_or_offset_state == 1:
                    self.update_level_masl_from_head(obsid, fr_d_t, to_d_t, self.LoggerPos.text())
                else:
                    self.update_level_masl_from_level_masl(obsid, fr_d_t, to_d_t, self.Add2Levelmasl.text())

                self.getlastcalibration()
            else:
                utils.pop_up_info("Calibration aborted!!\nThere must not be empty cells or\nnull values in the 'head_cm' column!")
        else:
            self.INFO.setText("Select the observation point with logger data to be calibrated.")
        self.calib_help.setText("")
        PyQt4.QtGui.QApplication.restoreOverrideCursor()

    def update_level_masl_from_level_masl(self, obsid, fr_d_t, to_d_t, newzref):
        """ Updates the level masl using newzref
        :param obsid: (str) The obsid
        :param fr_d_t: (datetime) start of calibration
        :param to_d_t: (datetime) end of calibration
        :param newzref: (int/float/str [m]) The correction that should be made against the head [m]
        :return: None
        """
        sql =r"""UPDATE w_levels_logger SET level_masl = """
        sql += str(newzref)
        sql += """ + level_masl WHERE obsid = '"""
        sql += obsid
        # Sqlite seems to have problems with date comparison date_time >= a_date, so they have to be converted into total seconds first.
        sql += """' AND CAST(strftime('%s', date_time) AS NUMERIC) > """
        sql += str((fr_d_t - datetime.datetime(1970,1,1)).total_seconds())
        sql += """ AND CAST(strftime('%s', date_time) AS NUMERIC) < """
        sql += str((to_d_t - datetime.datetime(1970,1,1)).total_seconds())
        sql += """ """
        dummy = utils.sql_alter_db(sql)

    def update_level_masl_from_head(self, obsid, fr_d_t, to_d_t, newzref):
        """ Updates the level masl using newzref
        :param obsid: (str) The obsid
        :param fr_d_t: (datetime) start of calibration
        :param to_d_t: (datetime) end of calibration
        :param newzref: (int/float/str [m]) The correction that should be made against the head [m]
        :return: None
        """
        sql =r"""UPDATE w_levels_logger SET level_masl = """
        sql += str(newzref)
        sql += """ + head_cm / 100 WHERE obsid = '"""
        sql += obsid
        # Sqlite seems to have problems with date comparison date_time >= a_date, so they have to be converted into total seconds first (but now we changed to > but kept .total_seconds())
        sql += """' AND CAST(strftime('%s', date_time) AS NUMERIC) > """
        sql += str((fr_d_t - datetime.datetime(1970,1,1)).total_seconds())
        sql += """ AND CAST(strftime('%s', date_time) AS NUMERIC) < """
        sql += str((to_d_t - datetime.datetime(1970,1,1)).total_seconds())
        sql += """ """
        dummy = utils.sql_alter_db(sql)

    def sql_into_recarray(self, sql):
        """ Converts and runs an sql-string and turns the answer into an np.recarray and returns it""" 
        my_format = [('date_time', datetime.datetime), ('values', float)] #Define (with help from function datetime) a good format for numpy array     
        recs = utils.sql_load_fr_db(sql)[1]
        table = np.array(recs, dtype=my_format)  #NDARRAY
        table2=table.view(np.recarray)   # RECARRAY   Makes the two columns inte callable objects, i.e. write table2.values 
        return table2        

    def update_plot(self):
        """ Plots self.level_masl_ts, self.meas_ts and maybe self.head_ts """
        self.reset_plot_selects_and_calib_help()
        self.calib_help.setText("Updating plot")
        PyQt4.QtGui.QApplication.setOverrideCursor(PyQt4.QtCore.Qt.WaitCursor)
        obsid = self.load_obsid_and_init()
        if obsid == None:
            PyQt4.QtGui.QApplication.restoreOverrideCursor()
            self.calib_help.setText("")
            return
        self.axes.clear()
        
        p=[None]*2 # List for plot objects
    
        # Load manual reading (full time series) for the obsid
        self.plot_recarray(self.axes, self.meas_ts, obsid, 'o-', 10)
        
        # Load Loggerlevels (full time series) for the obsid
        if self.loggerLineNodes.isChecked():
            logger_line_style = '.-'
        else:
            logger_line_style = '-'                
        self.plot_recarray(self.axes, self.level_masl_ts, obsid + unicode(' logger', 'utf-8'), logger_line_style, 10)

        #Plot the original head_cm
        if self.plot_logger_head.isChecked():
            self.plot_recarray(self.axes, self.head_ts, obsid + unicode(' original logger head', 'utf-8'), logger_line_style, 10)

        """ Finish plot """
        self.axes.grid(True)
        self.axes.yaxis.set_major_formatter(tick.ScalarFormatter(useOffset=False, useMathText=False))
        self.calibrplotfigure.autofmt_xdate()
        self.axes.set_ylabel(unicode('Level (masl)', 'utf-8'))  #This is the method that accepts even national characters ('åäö') in matplotlib axes labels
        self.axes.set_title(unicode('Plot for ', 'utf-8') + str(obsid))  #This is the method that accepts even national characters ('åäö') in matplotlib axes labels
        for label in self.axes.xaxis.get_ticklabels():
            label.set_fontsize(10)
        for label in self.axes.yaxis.get_ticklabels():
            label.set_fontsize(10)
        #plt.show()
        self.calibrplotfigure.tight_layout()
        self.canvas.draw()
        plt.close(self.calibrplotfigure)#this closes reference to self.calibrplotfigure
        PyQt4.QtGui.QApplication.restoreOverrideCursor()
        self.calib_help.setText("")

        self.getlastcalibration()

    def plot_recarray(self, axes, a_recarray, lable, line_style, picker=10):
        """ Plots a recarray to the supplied axes object """
        # Get help from function datestr2num to get date and time into float
        myTimestring = [a_recarray.date_time[idx] for idx in xrange(len(a_recarray))]
        numtime=datestr2num(myTimestring)  #conv list of strings to numpy.ndarray of floats
        axes.plot_date(numtime, a_recarray.values, line_style, label=lable, picker=picker)

    def set_from_date_from_x(self):
        """ Used to set the self.FromDateTime by clicking on a line node in the plot self.canvas """
        self.reset_plot_selects_and_calib_help()
        self.calib_help.setText("Select a node to use as \"from\"")
        self.deactivate_pan_zoom()
        self.canvas.setFocusPolicy(Qt.ClickFocus)
        self.canvas.setFocus()   
        self.cid.append(self.canvas.mpl_connect('pick_event', lambda event: self.set_date_from_x_onclick(event, self.FromDateTime)))

    def set_to_date_from_x(self):
        """ Used to set the self.ToDateTime by clicking on a line node in the plot self.canvas """    
        self.reset_plot_selects_and_calib_help()
        self.calib_help.setText("Select a node to use as \"to\"")
        self.deactivate_pan_zoom()
        self.canvas.setFocusPolicy(Qt.ClickFocus)
        self.canvas.setFocus()   
        self.cid.append(self.canvas.mpl_connect('pick_event', lambda event: self.set_date_from_x_onclick(event, self.ToDateTime)))

    def set_date_from_x_onclick(self, event, date_holder):
        """ Sets the date_holder to a date from a line node closest to the pick event

            date_holder: a QDateTimeEdit object.
        """
        found_date = utils.find_nearest_date_from_event(event)
        date_holder.setDateTime(found_date)           
        self.reset_plot_selects_and_calib_help()
    
    def reset_plot_selects_and_calib_help(self):
        """ Reset self.cid and self.calib_help """
        self.reset_cid()
        self.log_pos = None
        self.y_pos = None
        self.calib_help.setText("")

    def reset_cid(self):
        """ Resets self.cid to an empty list and disconnects unused events """
        for x in self.cid:
            self.canvas.mpl_disconnect(x)
        self.cid = []

    def catch_old_level(self):
        """Part of adjustment method 3. adjust level_masl by clicking in plot.
        this part selects a line node and a y-position on the plot"""
        #Run init to make sure self.meas_ts and self.head_ts is updated for the current obsid.           
        self.load_obsid_and_init()
        self.deactivate_pan_zoom()
        self.canvas.setFocusPolicy(Qt.ClickFocus)
        self.canvas.setFocus()

        self.calib_help.setText("Select a logger node.")
        self.cid.append(self.canvas.mpl_connect('pick_event', self.set_log_pos_from_node_date_click))
            
    def catch_new_level(self):
        """ Part of adjustment method 3. adjust level_masl by clicking in plot.
        this part selects a y-position from the plot (normally user would select a manual measurement)."""
        if self.log_pos is not None:
            self.calib_help.setText("Select a y position to move to.")
            self.cid.append(self.canvas.mpl_connect('button_press_event', self.set_y_pos_from_y_click))
            self.calib_help.setText("")
        else:
            self.calib_help.setText("Something wrong, click \"Current\" and try again.")

    def calculate_offset(self):
        """ Part of adjustment method 3. adjust level_masl by clicking in plot.
        this method extracts the head from head_ts with the same date as the line node.
            4. Calculating y-position - head (or level_masl) and setting self.LoggerPos.
            5. Run calibration.
        """            
        if self.log_pos is not None and self.y_pos is not None:
            PyQt4.QtGui.QApplication.setOverrideCursor(PyQt4.QtCore.Qt.WaitCursor)

            logger_ts = self.level_masl_ts
            
            y_pos = self.y_pos
            log_pos = self.log_pos
            self.y_pos = None
            self.log_pos = None
            log_pos_date = datestring_to_date(log_pos).replace(tzinfo=None)
            logger_value = None

            #Get the value for the selected node
            for raw_date, logger_value in logger_ts:
                date = datestring_to_date(raw_date).replace(tzinfo=None)
                if date == log_pos_date:
                    break

            if logger_value is None:
                utils.pop_up_info("No connection between level_masl dates and logger date could be made!\nTry again or choose a new logger line node!")
            else:
                self.Add2Levelmasl.setText(str(float(y_pos) - float(logger_value)))

                PyQt4.QtGui.QApplication.restoreOverrideCursor()

        self.pushButtonMpos.setEnabled(False)
        
    def set_log_pos_from_node_date_click(self, event):
        """ Sets self.log_pos variable to the date (x-axis) from the node nearest the pick event """
        found_date = utils.find_nearest_date_from_event(event)
        #self.calib_help.setText("Logger node " + str(found_date) + " selected, click button \"Calibrate by selection in plot\" again.")
        self.calib_help.setText("Logger node " + str(found_date) + " selected, click \"new\" and select new level.")
        self.log_pos = found_date
        self.reset_cid()
        self.pushButtonMpos.setEnabled(True)
 
    def set_y_pos_from_y_click(self, event):
        """ Sets the self.y_pos variable to the y value of the click event """
        self.y_pos = event.ydata
        #self.calib_help.setText("Y position set, click button \"Calibrate by selection in plot\" again for calibration.")
        self.calculate_offset()
        self.calib_help.setText("Offset is calculated, now click \"add\".")
        self.reset_cid()

    def logger_pos_best_fit(self):
        self.loggerpos_masl_or_offset_state = 1
        self.calc_best_fit()

    def level_masl_best_fit(self):
        self.loggerpos_masl_or_offset_state = 0
        self.calc_best_fit()
        
    def calc_best_fit(self):
        """ Calculates the self.LoggerPos from self.meas_ts and self.head_ts
        
            First matches measurements from self.meas_ts to logger values from
            self.head_ts. This is done by making a mean of all logger values inside
            self.meas_ts date - search_radius and self.meas_ts date + search_radius.
            (this could probably be change to get only the closest logger value
            inside the search_radius instead)
            (search_radius is gotten from self.get_search_radius())
            
            Then calculates the mean of all matches and set to self.LoggerPos.
        """
        obsid = self.load_obsid_and_init()
        self.reset_plot_selects_and_calib_help()
        search_radius = self.get_search_radius()
        if self.loggerpos_masl_or_offset_state == 1:# UPDATE TO RELEVANT TEXT
            logger_ts = self.head_ts
            text_field = self.LoggerPos
            calib_func = self.set_logger_pos
            really_calibrate_question = utils.askuser("YesNo", """This will calibrate all values inside the chosen period\nusing the mean difference between head_cm and w_levels measurements.\n\nSearch radius for matching logger and measurement nodes set to '""" + ' '.join(search_radius) + """'\n\nContinue?""")
        else:# UPDATE TO RELEVANT TEXT
            logger_ts = self.level_masl_ts
            text_field = self.Add2Levelmasl
            calib_func = self.add_to_level_masl
            really_calibrate_question = utils.askuser("YesNo", """This will calibrate all values inside the chosen period\nusing the mean difference between level_masl and w_levels measurements.\n\nSearch radius for matching logger and measurement nodes set to '""" + ' '.join(search_radius) + """'\n\nContinue?""")
        if really_calibrate_question.result == 0: # if the user wants to abort
            return

        PyQt4.QtGui.QApplication.setOverrideCursor(PyQt4.QtCore.Qt.WaitCursor)

        coupled_vals = self.match_ts_values(self.meas_ts, logger_ts, search_radius)
        if not coupled_vals:
            utils.pop_up_info("There was no matched measurements or logger values inside the chosen period.\n Try to increase the search radius!")
        else:
            text_field.setText(str(utils.calc_mean_diff(coupled_vals)))
            calib_func()

        PyQt4.QtGui.QApplication.restoreOverrideCursor()
     
    def match_ts_values(self, meas_ts, logger_ts, search_radius_tuple):
        """ Matches two timeseries values for shared timesteps 
        
            For every measurement point, a mean of logger values inside 
            measurementpoint + x minutes to measurementpoint - x minutes
            is coupled together.

            At the first used measurement, only logger values greater than
            the set start date is used.
            At the last measurement, only logger values lesser than the set end
            date is used.
            This is done so that values from another logger reposition is not
            mixed with the chosen logger positioning. (Hard to explain).
        """
        coupled_vals = []
        
        #Get the search radius, default to 10 minutes
        search_radius = int(search_radius_tuple[0])
        search_radius_period = search_radius_tuple[1]
  
        logger_gen = utils.ts_gen(logger_ts)
        try:
            l = next(logger_gen)
        except StopIteration:
            return None
        log_vals = []

        all_done = False
        #The .replace(tzinfo=None) is used to remove info about timezone. Needed for the comparisons. This should not be a problem though as the date scale in the plot is based on the dates from the database. 
        outer_begin = self.FromDateTime.dateTime().toPyDateTime().replace(tzinfo=None)
        outer_end = self.ToDateTime.dateTime().toPyDateTime().replace(tzinfo=None)
        logger_step = datestring_to_date(l[0]).replace(tzinfo=None)
        for m in meas_ts:
            if logger_step is None:
                break
            meas_step = datestring_to_date(m[0]).replace(tzinfo=None)

            step_begin = dateshift(meas_step, -search_radius, search_radius_period)
            step_end = dateshift(meas_step, search_radius, search_radius_period)

            if step_end < outer_begin:
                continue
            if step_begin > outer_end:
                break

            #Skip logger steps that are earlier than the chosen begin date or are not inside the measurement period.
            while logger_step < step_begin or logger_step < outer_begin:
                try:
                    l = next(logger_gen)
                except StopIteration:
                    all_done = True
                    break
                logger_step = datestring_to_date(l[0]).replace(tzinfo=None)

            log_vals = []

            while logger_step is not None and step_begin <= logger_step <= step_end and outer_begin <= logger_step <= outer_end:
                if not math.isnan(float(l[1])) or l[1] in ('nan', 'NULL'):
                    log_vals.append(float(l[1]))
                try:
                    l = next(logger_gen)
                except StopIteration:
                    all_done = True
                    break
                logger_step = datestring_to_date(l[0]).replace(tzinfo=None)                     

            if log_vals:
                mean = np.mean(log_vals)
                if not math.isnan(mean):
                    coupled_vals.append((m[1], mean))
            if all_done:
                break
        return coupled_vals
                      
    def get_search_radius(self):
        """ Get the period search radius, default to 10 minutes """
        if not self.bestFitSearchRadius.text():
            search_radius = '10 minutes'
            self.bestFitSearchRadius.setText(search_radius)
        else:
            search_radius = self.bestFitSearchRadius.text()

        search_radius_splitted = search_radius.split()
        if len(search_radius_splitted) != 2:
            utils.pop_up_info("Must write time resolution also, ex. 10 minutes")
        return tuple(search_radius_splitted)

    def deactivate_pan_zoom(self):
        """ Deactivates the NavigationToolbar pan or zoom feature if they are currently active """
        if self.mpltoolbar._active == "PAN":
            self.mpltoolbar.pan()
        elif self.mpltoolbar._active == "ZOOM":
            self.mpltoolbar.zoom()

    def delete_selected_range(self, table_name):
        """ Deletes the current selected range from the database from w_levels_logger
        :return: De
        """
        current_loaded_obsid = self.obsid
        selected_obsid = self.load_obsid_and_init()
        if current_loaded_obsid != selected_obsid:
            utils.pop_up_info("Error!\n The obsid selection has been changed but the plot has not been updated. No deletion done.\nUpdating plot.")
            self.update_plot()
            return
        elif selected_obsid is None:
            utils.pop_up_info("Error!\n No obsid was selected. No deletion done.\nUpdating plot.")
            self.update_plot()
            return

        fr_d_t = str((self.FromDateTime.dateTime().toPyDateTime() - datetime.datetime(1970,1,1)).total_seconds())
        to_d_t = str((self.ToDateTime.dateTime().toPyDateTime() - datetime.datetime(1970,1,1)).total_seconds())

        sql_list = []
        sql_list.append(r"""delete from "%s" """%table_name)
        sql_list.append(r"""where obsid = '%s' """%selected_obsid)
        sql_list.append(r"""AND CAST(strftime('%s', date_time) AS NUMERIC) """)
        sql_list.append(r""" > '%s' """%fr_d_t)
        sql_list.append(r"""AND CAST(strftime('%s', date_time) AS NUMERIC) """)
        sql_list.append(r""" < '%s' """%to_d_t)
        sql = ''.join(sql_list)

        really_delete = utils.askuser("YesNo", "Do you want to delete the period " +
                                      str(self.FromDateTime.dateTime().toPyDateTime()) + " to " +
                                      str(self.ToDateTime.dateTime().toPyDateTime()) +
                                      " for obsid " + selected_obsid + " from table " + table_name + "?").result
        if really_delete:
            utils.sql_alter_db(sql)
            self.update_plot()
class MatplotlibWidgetWL(QGraphicsView):
    def __init__(self, parent = None):
        QWidget.__init__(self, parent)
        self.canvas = MplCanvas()
        self.vbl = QVBoxLayout()
        self.vbl.addWidget(self.canvas)
        self.setLayout(self.vbl)
        self.canvas.ax.set_title('Series of Averages', fontsize=12)
        self.canvas.fig.patch.set_alpha(0)
        self.canvas.fig.tight_layout()
        self.mpl_toolbar = NavigationToolbar(self.canvas, self)
        self.canvas.mpl_connect('button_press_event', self.onclick)
        self.mpl_toolbar.pan()
        params = {
                  'xtick.labelsize': 12,
                  'ytick.labelsize': 12,
                  'figure.autolayout': True,
                }
        plt.rcParams.update(params)
        self.data = []
        self.distmeshsurf = 1.
        if sys.platform == 'darwin':
            self.filePath = '/Users/TPSGroup/Documents/Experimental Data/Data Mike/Raw Data/2015'
        else:
            self.filePath = 'C:\\Users\\tpsgroup\\Desktop\\Documents\\Data Mike\\Raw Data\\2015'
        self.trace = [False, False, False, False]
            
    pickedValReady = pyqtSignal(object)
    
    def onclick(self, event):
        if event.button == 3:
            self.pickedValReady.emit(event.xdata)

    def addTrace(self):
        # average traces saved as (paramter, surface, surface err, field, field err)
        datapath = QFileDialog.getOpenFileNames(self, 'Select Avgerage Trace File', self.filePath, '(*.txt)')
        if not datapath: return
        for i in range(len(datapath)):
            self.data.append(loadtxt(str(datapath[i]), skiprows=2))
        self.filePath = os.path.dirname(str(datapath[0]))

    def kRange(self, n, ml):
        '''Stark states in parabolic quantum number k(n_1-n_2), {k}=-(n-|m_l|-1)...(n-|m_l|-1),
        (n-|m_l|) elements, elements the same for m_l=0, +/-2 where maxkmax states have pure m_l=0
        character, these two states are 'missing' at the edge of the manifold for m_l=+/-2'''
        kRange = [i for i in range(-(n-abs(ml)-1),(n-abs(ml)),2)]
        return kRange

    def StarkEnergy(self, n, ml, k, F):
        # Hartree in wavenumbers, Rydberg constant in cm^-1
        # Rydberg constant for Hydrogen != R_inf
        rh = 109677.583 
        hartree = 2*rh
        Eau = (-(1./(2*n**2)) + 1.5*n*k*F - (n**4)/16.0*(17*n**2 - 3*k**2 - 9*ml**2 + 19)*F**2 + \
              3/32*n**7*k*(23*n**2 - k**2 + 11*ml**2 + 39)*F**3 - \
              (n**10)/1024.0*(5487*n**4 + 35182*n**2 - 1134*ml**2*k**2 + \
              1806*n**2*k**2 - 3402*n**2*ml**2 - 3093*k**4 - 549*ml**4 + \
              5754*k**2 - 8622*ml**2 + 16211)*F**4)*hartree
        return Eau

    def plotSpectrum(self, n, ml02j32flag, ml1j32flag, ml02j12flag, ml1j12flag, trace, d, volt, offset, smooth, smoothwin, smoothpol, normalise):
        if len(self.data) < 1: return
        # get curent xy limits
        xlim1, xlim2 = self.canvas.ax.get_xlim()
        ylim1, ylim2 = self.canvas.ax.get_ylim()
        self.canvas.ax.clear()
        self.distmeshsurf = d
        # build Stark manifold from expansion for energies in E-field
        # from http://physics.nist.gov/asd
        Lalphaj32 = -82259.2850014 #121.5668237310
        Lalphaj12 =  -82258.919113 #121.5673644609
        rh = 109677.583
        c = 299792458
        # in eV
        h = 4.135667662E-15
        # Electric field in V/cm to atomic units E_h/ea_0.
        #http://physics.nist.gov/cgi-bin/cuu/Value?auefld 
        Fau = (100*volt/(5.142206E11))/d
        # energies converted to nm
        # account for fine splitting due to spin-orbit coupling
        # if not, from expansion: en = (2*10**7)/(self.StarkEnergy(n, 2, k, Fau) - self.StarkEnergy(2, 0, 1, Fau)) + offset
        kml02 = self.kRange(n, 0)
        kml1 = self.kRange(n, 1)
        if ml02j32flag:
            ml02j32 = [0]*len(kml02)
            for i in range(len(kml02)):
                ml02j32[i] = (2*10**7)/(self.StarkEnergy(n, 2, kml02[i], Fau) - (-rh-Lalphaj32)) + offset
        if ml1j32flag:
            ml1j32 = [0]*len(kml1)
            for i in range(len(kml1)):
                ml1j32[i] = (2*10**7)/(self.StarkEnergy(n, 1, kml1[i], Fau) - (-rh-Lalphaj32)) + offset
        if ml02j12flag:
            ml02j12 = [0]*len(kml02)
            for i in range(len(kml02)):
                ml02j12[i] = (2*10**7)/(self.StarkEnergy(n, 2, kml02[i], Fau) -  (-rh-Lalphaj12)) + offset
        if ml1j12flag:
            ml1j12 = [0]*len(kml1)
            for i in range(len(kml1)):
                ml1j12[i] = (2*10**7)/(self.StarkEnergy(n, 1, kml1[i], Fau) -  (-rh-Lalphaj12)) + offset
               
        colors = ['0.0','0.2','0.4','0.6']
        ls = ['-','-','-','-']
        c = ['k', 'g', 'm', 'y']
        for i in range(len(self.data)):
            data = self.data[i]
            self.trace[i] = trace
            if self.trace[i]:
                argy = data[:,3]
                maxn = max(data[:,3])
            else:
                argy = data[:,1]
                maxn = max(data[:,1])
            if smooth:
                argx = savitzky_golay(data[:,0], smoothwin, smoothpol)
                argy = savitzky_golay(argy, smoothwin, smoothpol)
            else:
                argx = data[:,0]
            if normalise:
                argy = argy/maxn
            self.canvas.ax.plot(argx, argy, linestyle=ls[i], color=c[i], linewidth=1.4) 
            
        if ml02j32flag:
            xx = [ml02j32, ml02j32]
            yy = [[-0.08]*len(ml02j32), [1.02]*len(ml02j32)]
            self.canvas.ax.plot(xx,yy, 'b', linewidth=1.2)
            for i in range(len(ml02j32)):
                self.canvas.ax.text(ml02j32[i], 1.06, str(kml02[i]), horizontalalignment='center', \
                verticalalignment='center',color='b',fontsize=8)
        if ml1j32flag:
            xx = [ml1j32, ml1j32]
            yy = [[-0.08]*len(ml1j32), [1.02]*len(ml1j32)]
            self.canvas.ax.plot(xx,yy, 'b--', linewidth=1.2)
            for i in range(len(ml1j32)):
                self.canvas.ax.text(ml1j32[i], 1.06, str(kml1[i]), horizontalalignment='center', \
                verticalalignment='center',color='b',fontsize=8)
        if ml02j12flag:
            xx = [ml02j12, ml02j12]
            yy = [[-0.08]*len(ml02j12), [1.02]*len(ml02j12)]
            self.canvas.ax.plot(xx,yy, 'r', linewidth=1.2)
            for i in range(len(ml02j12)):
                self.canvas.ax.text(ml02j12[i], 1.06, str(kml02[i]), horizontalalignment='center', \
                verticalalignment='center',color='r',fontsize=8)
        if ml1j12flag:
            xx = [ml1j12, ml1j12]
            yy = [[-0.08]*len(ml1j12), [1.02]*len(ml1j12)]
            self.canvas.ax.plot(xx,yy, 'r--', linewidth=1.2)
            for i in range(len(ml1j12)):
                self.canvas.ax.text(ml1j12[i], 1.06, str(kml1[i]), horizontalalignment='center', \
                verticalalignment='center',color='r',fontsize=8)

        self.canvas.ax.set_xlabel("Fundamental Wavelength (nm)")
        self.canvas.ax.set_title('Stark Manifold for n= ' + str(n), fontsize=12)
        if (xlim1 == 0.0 and xlim2 == 1.0):
            xlim1 = min(argx)
            xlim2 = max(argx)
            ylim1 = 0
            ylim2 = 1.1
        self.canvas.ax.set_ylim(ymin=ylim1, ymax=ylim2)
        self.canvas.ax.set_xlim(xmin=xlim1, xmax=xlim2)
        self.canvas.draw()

    def clearDisplay(self):
        self.canvas.ax.clear()
        self.canvas.ax.set_title("", fontsize=12)
        self.data = []
        self.trace = [False, False, False, False]
        self.canvas.draw()
Esempio n. 18
0
class Window(QtGui.QDialog):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure)

        self.toolbar = NavigationToolbar(self.canvas, self)
        self.toolbar.hide()

        # Just some button
        self.button = QtGui.QPushButton('Plot')
        self.button.clicked.connect(self.plot)

        self.button1 = QtGui.QPushButton('Zoom')
        self.button1.clicked.connect(self.zoom)

        self.button2 = QtGui.QPushButton('Pan')
        self.button2.clicked.connect(self.pan)

        self.button3 = QtGui.QPushButton('Home')
        self.button3.clicked.connect(self.home)

        # set the layout
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)
        layout.addWidget(self.button)
        layout.addWidget(self.button1)
        layout.addWidget(self.button2)
        layout.addWidget(self.button3)
        self.setLayout(layout)

    def home(self):
        self.toolbar.home()

    def zoom(self):
        self.toolbar.zoom()

    def pan(self):
        self.toolbar.pan()

    def plot(self):
        ''' DO NOT CHANGE. Original sample '''
        #data = [random.random() for i in range(25)]
        #ax = self.figure.add_subplot(111)      # create an axis
        #ax.hold(False)                         # discards the old graph
        #ax.plot(data, '*-')                    # plot data
        #self.canvas.draw()                     # refresh canvas

        ra = [45, 40, 90, -75, 80.2,
              102.63]  # angle  --> change to buffer_angle[4000]
        ra = [x / 180.0 * 3.141593 for x in ra]  # convert angle to radian
        dec = [1.01, 6.05, 5.6, 4.02, 9.1,
               7.85]  # distance --> change to buffer_distance[4000]

        ax = self.figure.add_axes([0.1, 0.1, 0.8, 0.8], polar=True)

        ax.set_ylim(0, 10.0)
        ax.set_yticks(numpy.arange(0, 6, 2))
        ax.scatter(ra, dec, c='r')  # plot the first microphone

        self.canvas.draw()
class MatplotlibWidgetRydSeries(QGraphicsView):
    def __init__(self, parent = None):
        QWidget.__init__(self, parent)
        self.canvas = MplCanvas()
        self.vbl = QVBoxLayout()
        self.vbl.addWidget(self.canvas)
        self.setLayout(self.vbl)
        self.canvas.ax.set_title('Rydberg Series', fontsize=12)
        self.canvas.setFocusPolicy(Qt.StrongFocus)
        self.canvas.setFocus()
        self.canvas.fig.patch.set_alpha(0)
        self.mpl_toolbar = NavigationToolbar(self.canvas, self)
        params = {
                  'legend.fontsize': 12,
                  'xtick.labelsize': 12,
                  'ytick.labelsize': 12,
                  'legend.handletextpad': .5,
                  'figure.autolayout': True,
                }
        plt.rcParams.update(params)
        self.canvas.mpl_connect('button_press_event', self.onclick)
        self.mpl_toolbar.pan()
        self.clearflag = False
        self.defaultloaded = False
        self.filePath = 'C:\\Users\\tpsgroup\\Desktop\\Documents\\Data Mike'
    
    pickedValReady = pyqtSignal(object)
    
    def defaultSet(self, bool):
        self.defaultloaded = bool
    
    def plotWLScan(self,laseroffset):
        '''display complete WL scan and Rydberg series on top'''
        dataField = loadtxt('FullWavelengthScanField.txt')
        dataSurface = loadtxt('FullWavelengthScanSurface.txt')
        argYField = dataField[:,1]/max(dataField[:,1])
        argYSurface = dataSurface[:,1]/max(dataSurface[:,1])
        self.canvas.ax.clear()
        self.canvas.ax.plot(dataField[:,0], argYField, 'k', label="Field Signal", linewidth=1.5)
        self.canvas.ax.plot(dataSurface[:,0], argYSurface, 'g', label="Surface Signal", linewidth=1.5)
        self.canvas.ax.set_xlabel("Fundamental Wavelength (nm)", fontsize=12)
        self.canvas.ax.set_title('Rydberg Series', fontsize=12)
        self.canvas.ax.legend(loc="upper right",  bbox_to_anchor = [.98,0.86], fontsize=12)
        self.canvas.ax.set_ylim([-0.02,1.12])
        self.plotRydSeries(laseroffset)
        self.canvas.fig.tight_layout()
        self.canvas.draw()
        self.defaultloaded = True

    def addTrace(self):
        datapath = QFileDialog.getOpenFileName(self, 'Select WL Scan File', self.filePath, '(*.txt)')
        if not datapath: return
        self.filePath = os.path.dirname(str(datapath))
        if len(datapath) < 1: return
        data = loadtxt(str(datapath))
        argY = data[:,1]/max(data[:,1])
        if self.defaultloaded:
            self.canvas.ax.plot(data[:,0], argY, 'r', label="Field Signal", linewidth=1.5)
        else:
            self.canvas.ax.plot(data[:,0], argY, 'k', label="Field Signal", linewidth=1.5)
        self.canvas.draw()
        

    def clearDisplay(self):
        self.canvas.ax.cla()
        self.canvas.draw()
        self.clearflag = True
        self.defaultloaded = False

    def onclick(self, event):
        if event.button == 3:
            self.pickedValReady.emit(event.xdata)

    def plotRydSeries(self, laseroffset):
        # Rydberg constant for Hydrogen
        rh = 109677.583
        nRange = np.arange(15, 71)
        j32offset = 0.091 # 1/64*alpha^2*Ryd
        rydEn = (2.*10**7)/(rh*(0.25 - (1./nRange**2)) - j32offset) + laseroffset
        if not(self.clearflag):
            if hasattr(self, 'rydlines') and len(self.canvas.ax.lines) > 0:
                for i in range(np.size(self.rydlines)):
                    self.canvas.ax.lines.remove(self.rydlines[i])
            if hasattr(self, 'rydlabels') and len(self.canvas.ax.texts) > 0:
                 for i in range(np.size(self.rydlines)):
                    self.rydlabels[i].remove()
        xx = (rydEn, rydEn)
        yy = (np.ones(np.size(rydEn))*-0.02,np.ones(np.size(rydEn))*1.02)
        self.rydlines = self.canvas.ax.plot(xx,yy,linewidth=1,color='b')
        labels = nRange.astype(str)
        self.rydlabels = {}       
        for i in range(np.size(labels)):
            self.rydlabels[i] = self.canvas.ax.text(rydEn[i], 1.06, labels[i],
        horizontalalignment='center',verticalalignment='center',color='b',fontsize=12)
        self.canvas.draw()
        self.clearflag = False
class Application(object):
    """
    Main application class without GUI.
    """
    def __init__(self, args):
        """
        Initialize the main application.

        Args:
            args: the arguments given by the ArgumentParser
        """
        super(Application, self).__init__()

        self.is_init = False
        self.args = args

        #default settings of the program
        self.defaults = DefaultProgSettings()
        if not self.args.reset:
            self.defaults.load_settings()

        self.frame_status = FrameStatus()
        #self.frame_status.set_status("pan")

        self.filter_status = FilterStatus()
        #self.filter_status.set_status("pan")

        self._cmaps = sorted(m for m in plt.cm.datad if not m.endswith("_r"))

        self.image = ImageLab("")

        #open initial file
        if os.path.isfile(self.defaults.img_fname):
            self.open_sis(self.defaults.img_fname)
        else:
            self.open_sis()

        #create panels for the images
        self.frames_panel = FramesCanvas(
            self.image,
            width=5,
            height=4,
            dpi=100,
            show_areas=self.defaults.show_regions,
            show_contour=self.defaults.show_contour,
            show_grid=self.defaults.show_grid)
        self.filter_panel = FFTCanvas(self.image,
                                      width=5,
                                      height=4,
                                      dpi=100,
                                      show_mask=self.defaults.show_mask)


        self.vlim_frame_panel = \
                        VlimPanel(init_values=self.defaults.vlim_img_corr)
        self.vlim_fft_panel = \
                        VlimPanel(scale=100, slide_range=(-200, 200),
                                  init_values=self.defaults.vlim_fft_corr)

        self.results_window = None
        self.progress_bar = None

        self.filter_panel.set_image(self.image)
        self.frames_panel.set_image(self.image)

        if os.path.isfile(self.defaults.mask_fname):
            self.open_mask(self.defaults.mask_fname)

        self.fft_frame_menu = QtGui.QMenu()
        self.status_bar = QtGui.QStatusBar()

        self.toolbar_frame = NavigationToolbar(self.frames_panel, None)
        self.toolbar_filter = NavigationToolbar(self.filter_panel, None)

        self.nav_panel_filter = FilterZoomPanel(self._set_pan_filter,
                                                self._set_filter)
        self.nav_panel_frames = FramesZoomPanel(self._set_pan_frames,
                                                self._set_pick_coords)

        self._set_pan_frames()
        self._set_pan_filter()

    def open_sis(self, fname=""):
        """
        Open a sis image file.

        Args:
            fname (string): optional filename, if empty it will be asked
        """
        def_fname = self.image.filename
        if fname == "":
            #if no filename is give ask it
            fname = QtGui.QFileDialog.getOpenFileName(
                self,
                'Open SIS file',
                def_fname.decode("utf-8"),
                filter="SIS image (*.sis)",
                options=FILE_DIALOG_OPT)
            #must convert QString to python string
            fname = str(fname)

            if fname != "":
                #if a filname was given ask details
                if OpenSisPopup.setParams(self.defaults,
                                          self.image,
                                          parent=self):
                    self._load_sis(fname)
                #otherwise if any image is currently loaded ask again
                elif self.image.filename == "":
                    self.open_sis()
            #otherwise if any image is currently loaded ask again
            elif self.image.filename == "":
                #confirm exit to avoid infinite dialogs if one doesn't want to open a file
                msg = "If you don't provide a valid file to open the program will be closed. Are you sure?"
                reply = QtGui.QMessageBox.question(
                    self, 'Close program', msg,
                    QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
                    QtGui.QMessageBox.Yes)
                if reply == QtGui.QMessageBox.Yes:
                    exit()
                else:
                    self.open_sis()
        else:
            #if a filename was give try to open it
            self._load_sis(fname)

        self.defaults.img_fname = fname

    def _load_sis(self, fname):
        """
        Loads into the program a given sis image file.

        Args:
            fname (string): filename of the sis file
        """
        if fname != "":

            self.image = ImageLab(
                filename=fname,
                frame_w=self.defaults.frame_width,
                frame_h=self.defaults.frame_height,
                frame_w_old=self.defaults.frame_width_old,
                frame_h_old=self.defaults.frame_height_old,
                frame_cols=self.defaults.frame_colums,
                frame_rows=self.defaults.frame_rows,
                frame_num=self.defaults.frame_number,
                sis_img_n=self.defaults.sis_img_number,
                vlim_img_corr=self.defaults.vlim_img_corr,
                vlim_fft_corr=self.defaults.vlim_fft_corr,
                skip_frames=self.defaults.skip_frames,
                cmap_img=self.defaults.frame_cmap,
                cmap_fft=self.defaults.fft_cmap,
                fft_frame_num=self.defaults.fft_frame_n,
                compensate_bkg=self.defaults.img_compensate_bkg,
                compensate_max=self.defaults.img_compensate_max,
                bkg_slice=self.defaults.slices_bkg,
                main_slice=self.defaults.slices_main,
                max_slice=self.defaults.slices_max,
                show_residuals=self.defaults.show_residuals,
                gauss_filter=self.defaults.gauss_filter)

            self.image.init(time_delta=self.defaults.time_delta)

            #update some defaults values because they may be corrected during
            #the ImageLab initialization
            self.defaults.slices_bkg = self.image.background_slices
            self.defaults.slices_max = self.image.maximum_slices
            self.defaults.slices_main = self.image.main_slices
            self.defaults.fft_frame_n = self.image.fft_frame_num
            self.defaults.frame_width_old = self.defaults.frame_width
            self.defaults.frame_height_old = self.defaults.frame_height
            self.defaults.frame_height = self.image.frame_h
            self.defaults.frame_width = self.image.frame_w

            #load the filter mask file if it exists
            if os.path.isfile(self.defaults.mask_fname):
                self.open_mask(self.defaults.mask_fname)

            #only if the GUI has been already initialized uptdate frames
            #and menu
            if self.is_init:
                self.status_bar.showMessage("File: \"%s\"" % fname)
                self.filter_panel.set_image(self.image)
                self.frames_panel.set_image(self.image)
                self.update_plots()
                self._update_fft_frame_menu()

    def open_mask(self, fname=""):
        """
        Loads a mask file for the fft filter.

        Args:
            fname (string): optional filename, if empty it will be asked
        """
        if fname == "":
            def_fname = os.path.splitext(self.image.filename)[0] + ".mask"
            fname = QtGui.QFileDialog.getOpenFileName(
                self,
                'Open mask file',
                def_fname.decode("utf-8"),
                filter="Mask CSV (*.mask)",
                options=FILE_DIALOG_OPT)
            fname = str(fname)
        if fname != "":
            with open(fname, "rb") as fid:
                reader = csv.DictReader(fid)
                self.image.filter_points_list = \
                                    [FilterPoint(**row) for row in reader]

            self.defaults.mask_fname = fname

            #only if the GUI has been already initialized update frames
            if self.is_init:
                self.update_plots()

    def save_sis(self):
        """
        Saves the frames to sis files.
        """
        def_fname = self.image.filename
        fname = QtGui.QFileDialog.getSaveFileName(self,
                                                  'Save sis files',
                                                  def_fname.decode("utf-8"),
                                                  filter="SIS (*.sis)",
                                                  options=FILE_DIALOG_OPT)
        fname = str(fname)
        if fname != "":
            self.defaults.sis_save_fname = fname

            if SaveSisPopup.setParams(self.defaults, self.image, parent=self):
                self.image.sis_writeimg(self.defaults.sis_save_fname,
                                        self.defaults.sis_save_format,
                                        self.defaults.sis_save_suffix)

    def save_mask(self):
        """
        Saves the mask of the current fft filter to a file.
        """
        def_fname = os.path.splitext(self.image.filename)[0] + ".mask"
        fname = QtGui.QFileDialog.getSaveFileName(self,
                                                  'Save mask file',
                                                  def_fname.decode("utf-8"),
                                                  filter="Mask CSV (*.mask)",
                                                  options=FILE_DIALOG_OPT)
        fname = str(fname)
        if fname != "":
            with open(fname, "wb") as fid:
                writer = csv.DictWriter(fid,
                                        ("mx", "my", "sx", "sy", "A", "e"))
                writer.writeheader()
                writer.writerows(
                    [p.get_point() for p in self.image.filter_points_list])

            self.defaults.mask_fname = fname

    def save_movie(self):
        """
        Save the movie of the frames to a file.
        """
        def_fname = os.path.splitext(self.image.filename)[0] + ".mp4"
        fname = QtGui.QFileDialog.getSaveFileName(
            self,
            'Save movie',
            def_fname.decode("utf-8"),
            filter="MPEG (*.mp4);;GIF (*.gif)",
            options=FILE_DIALOG_OPT)
        fname = str(fname)

        if fname != "":
            #check the class of the selected file extension
            test_mpeg = fname.lower().endswith((".mp4", ".avi", ".mkv"))
            test_img = fname.lower().endswith(".gif")

            if test_mpeg:
                #if the extension if of the mpeg class check in the defaults if
                #a valid encoder was already selected, otherwise set a default
                #one (this is to help systems where one of libav or ffmpeg is
                #not present)
                if self.defaults.movie_writer not in ["libav", "ffmpeg"]:
                    self.defaults.movie_writer = "libav"
            elif test_img:
                #same for the image class
                self.defaults.movie_writer = "imagemagick"
            else:
                print "Error, utput movie format not supported."
                print "Supported formats: MP4, AVI, MKV, GIF"

            #if the format was valid get the parameters and write the movie
            if test_mpeg or test_img:
                if SaveMoviePopup.setParams(self.defaults,
                                            self.image,
                                            parent=self):
                    self._write_movie(fname)

    def _write_movie(self, fname):
        """
        Writes the frames movie to a file.

        Args:
            fname (string): filename of the movie
        """
        if fname != "":
            self.image.create_movie(filename=fname,
                                    fps=self.defaults.movie_fps,
                                    integral_x=self.defaults.movie_integrate_x,
                                    integral_y=self.defaults.movie_integrate_y,
                                    fading=self.defaults.movie_fading,
                                    use_frames=self.defaults.movie_frames,
                                    subframes=self.defaults.movie_subframes,
                                    dpi=self.defaults.movie_dpi,
                                    writer_name=self.defaults.movie_writer)
            self.status_bar.showMessage("Video saved to " + fname)

    def save_bitmap(self):
        """
        Saves the current frames bitmap to a file.
        """
        def_fname = os.path.splitext(self.image.filename)[0] + ".png"
        fname = QtGui.QFileDialog.getSaveFileName(
            self,
            'Save bitmap',
            def_fname.decode("utf-8"),
            filter="PNG (*.png);;JPEG (*.jpg)",
            options=FILE_DIALOG_OPT)
        fname = str(fname)
        if fname != "":
            if SaveBitmapPopup.setParams(self.defaults,
                                         self.image,
                                         parent=self):
                self.image.save_frames_bitmap(
                    filename=fname,
                    reorder=self.defaults.bitmap_reorder,
                    hor_crop=self.defaults.bitmap_hor_crop,
                    ver_crop=self.defaults.bitmap_ver_crop)

    def save_fft_bitmap(self):
        """
        Saves the current fft bitmap to a file.
        """
        def_fname = os.path.splitext(self.image.filename)[0] + "-fft.png"
        fname = QtGui.QFileDialog.getSaveFileName(
            self,
            'Save bitmap',
            def_fname.decode("utf-8"),
            filter="PNG (*.png);;JPEG (*.jpg)",
            options=FILE_DIALOG_OPT)
        fname = str(fname)
        if fname != "":
            self.image.save_fft_bitmap(filename=fname,
                                       show_mask=self.filter_panel.show_mask)

    def update_plots(self):
        """
        Updates all plots (fft and frames).
        """
        self.filter_panel.update_figure()
        self.frames_panel.update_figure(update_img=False)
        #TODO check when the update img is necessary for both

    def do_fit(self, fit_type="gauss"):
        """
        Handles the call for a fit.

        Args:
            fit_type (string): identifies the type of the fit
                "gauss" = Gaussian fit
                "tf" = Thomas-Fermi fit
                "bimodal" = Gaussian + Thomas-Fermin fit
        """

        #set progress bar updates
        self.progress_bar.setVisible(True)
        self.image.fit_done.connect(self._on_fitupdate)

        #initialize and call the fitting class
        if fit_type == "gauss":
            fit_class = fitting.Gauss2d
        elif fit_type == "tf":
            fit_class = fitting.ThomasFermi2d
        elif fit_type == "bimodal":
            fit_class = fitting.Bimodal2d
        else:
            print "Warning: wrong fit type, using gaussian"
            fit_class = fitting.Gauss2d

        self.image.do_fit(fit_class)

        #at the end update the contours in the image and results
        if self.image.show_residuals:
            #if the fit residuals are selected the image must be updated
            #after a new fit
            self.frames_panel.update_figure(update_img=True)
        self.frames_panel.update_contour()
        self.show_results()

        #hide progress bar
        self.progress_bar.setVisible(False)

    def _on_fitupdate(self, fract):
        """
        Updates the progress bar with the fraction passed as argument.

        Args:
            fract (float): number between 0 and 1 to be set in the progress bar
        """
        self.progress_bar.setValue(100.0 * float(fract))

    def show_results(self, new_window=True):
        """
        Shows the results of the fit in a window.

        Args:
            new_window (bool): open a new window if not already open
        """
        #enters if a window is present or it can be opened
        if (new_window) or\
           (not new_window and self.results_window is not None):

            #if the window is not opened open a new one
            if self.results_window == None:
                self.results_window = FitResultsPopup(parent=self)
                self.results_window.\
                        button_save.clicked.connect(self.save_results)
                self.results_window.show()

            #build the string conatining the results table
            results = "\t".join(self.image.results.keys()) + "\r\n"
            for n_id in sorted(self.image.results.frames_list()):
                dat = self.image.results.get_data(n_id)

                #if None is present write nothing
                row = "\t".join([format(dat[k], ".4g") \
                                 if dat[k] is not None \
                                 else "" \
                                 for k in self.image.results.keys()])
                results += row + "\r\n"

            #update the text
            self.results_window.text.setText(results)

            def _delete_window():
                """
                Deletes the results window for the application internal
                proprieties.
                """
                self.results_window = None

            #must use the custom window destroy for consistency
            self.results_window.destroyed.connect(_delete_window)

    def show_time_table(self):
        """
        Shows the configuration popup for setting the time intervals between
        frames.
        """
        if TimeTablePopup.setParams(self.defaults, self.image, parent=self):
            #update results window if needed
            self.show_results(new_window=False)

    def save_results(self):
        """
        Save the results of fit and coordinates pick to a file.
        """
        #check if there is something to save
        if len(self.image.results.frames_list()) > 0:
            def_fname = os.path.splitext(self.image.filename)[0] + ".csv"

            fname = QtGui.QFileDialog.getSaveFileName(
                self,
                'Save fit results',
                def_fname.decode("utf-8"),
                filter="CSV (*.csv)",
                options=FILE_DIALOG_OPT)
            fname = str(fname)

            if fname != "":
                with open(fname, "wb") as fid:
                    rows = [self.image.results.get_data(n_id) \
                            for n_id in self.image.results.frames_list()]

                    writer = csv.DictWriter(fid, self.image.results.keys())
                    writer.writeheader()
                    writer.writerows(rows)
        else:
            print "Warning: nothing to save"

    def _show_contour(self):
        """
        Called when there the user changes the fit contours visibility.
        """
        self.defaults.show_contour = not self.defaults.show_contour
        self.frames_panel.set_contour_visible(self.defaults.show_contour)

    def _show_residuals(self):
        """
        Called when there the user changes the fit residuals visibility.
        """
        self.defaults.show_residuals = not self.defaults.show_residuals
        self.image.show_residuals = self.defaults.show_residuals
        self.frames_panel.update_figure(update_img=True)

    def _show_areas(self):
        """
        Called when there the user changes the image areas visibility.
        """
        self.defaults.show_regions = not self.defaults.show_regions
        self.frames_panel.set_areas_visible(self.defaults.show_regions)

    def _show_grid(self):
        """
        Called when there the user changes the image grid visibility.
        """
        self.defaults.show_grid = not self.defaults.show_grid
        self.frames_panel.set_grid_visible(self.defaults.show_grid)

    def _show_mask(self):
        """
        Called when there the user changes the fft mask visibility.
        """
        self.filter_panel.show_mask = not self.filter_panel.show_mask
        self.defaults.show_mask = self.filter_panel.show_mask
        self.filter_panel.update_figure(update_img=False)

    def _compensate_max(self):
        """
        Called when there the user changes the image maximum normalization.
        """
        self.image.compensate_max = not self.image.compensate_max
        self.defaults.img_compensate_max = self.image.compensate_max
        #vlim must be updated
        self.image.vlim_img = (None, None)
        self.update_plots()

    def _compensate_bkg(self):
        """
        Called when there the user changes the image background compensation.
        """
        self.image.compensate_bkg = not self.image.compensate_bkg
        self.defaults.img_compensate_bkg = self.image.compensate_bkg
        #vlim must be updated
        self.image.vlim_img = (None, None)
        self.update_plots()

    def _set_cmap_fft(self, cmap):
        """
        Called when there the user changes fft color map.

        Args:
            cmap (string): color map name
        """
        self.image.cmap_fft = cmap
        self.filter_panel.update_figure(update_img=False)
        self.defaults.fft_cmap = cmap

    def _set_cmap_frame(self, cmap):
        """
        Called when there the user changes frames color map.

        Args:
            cmap (string): color map name
        """
        self.image.cmap_img = cmap
        self.frames_panel.update_figure(update_img=False)
        self.defaults.frame_cmap = cmap

    def _guess_areas(self):
        """
        Called when there the user ask for guessing the image areas.
        """
        self.image.guess_areas()
        self.frames_panel.update_areas()
        self.frames_panel.update_figure()
        self.defaults.slices_bkg = self.image.background_slices
        self.defaults.slices_max = self.image.maximum_slices
        self.defaults.slices_main = self.image.main_slices

    def _get_coord_frame(self, coords):
        """
        From the coordinates get the number of the frame, column and row.

        Args:
            coords (tuple): tuple of float coordinates
        """
        col = int(coords[0] / self.image.frame_w)
        row = int(coords[1] / self.image.frame_h)
        frame_num = row * self.image.frame_cols + col

        #return a negative number if the coordinates are negative
        if coords[0] < 0 or coords[1] < 0:
            frame_num = col = row = -1

        return (frame_num, col, row)

    def _set_min_area(self):
        """Changes the frame panel mode to the background area setting."""
        if self.frame_status.pan:
            self.toolbar_frame.pan()
        self.frame_status.set_status("min")
        self.nav_panel_frames.status.setText("set minimum")

    def _set_max_area(self):
        """Changes the frame panel mode to the maximum area setting."""
        if self.frame_status.pan:
            self.toolbar_frame.pan()
        self.frame_status.set_status("max")
        self.nav_panel_frames.status.setText("set maximum")

    def _set_main_area(self):
        """Changes the frame panel mode to the main area setting."""
        if self.frame_status.pan:
            self.toolbar_frame.pan()
        self.frame_status.set_status("main")
        self.nav_panel_frames.status.setText("set main")

    def _set_pick_coords(self, multi=False):
        """
        Changes the frame panel mode to the pick coordinates setting.
        If called while pick is active it goes in multiple selection mode.

        Args:
            multi (bool): keep the pick coordinates mode on for multiple
            selections
        """
        if self.frame_status.pan:
            self.toolbar_frame.pan()
        if self.frame_status.pick or multi:
            self.frame_status.set_status("pick_multi")
            self.nav_panel_frames.status.setText("multi pick")
        else:
            self.frame_status.set_status("pick")
            self.nav_panel_frames.status.setText("pick coordinates")

    def _set_pan_frames(self):
        """Changes the frame panel mode to pan/zoom."""
        if not self.frame_status.pan:
            self.toolbar_frame.pan()
        self.frame_status.set_status("pan")
        self.nav_panel_frames.status.setText("Pan/Zoom")

    def _set_pan_filter(self):
        """Changes the filter panel mode to pan/zoom."""
        if not self.filter_status.pan:
            self.toolbar_filter.pan()
        self.filter_status.set_status("pan")
        self.nav_panel_filter.status.setText("Pan/Zoom")

    def _set_filter(self):
        """Changes the filter panel mode to filtering mode."""
        if self.filter_status.pan:
            self.toolbar_filter.pan()
        self.filter_status.set_status("filter")
        self.nav_panel_filter.status.setText("Filter")

    def _set_gauss_sigma(self, text_control):
        """
        Changes the gaussian filter sigma width.

        Args:
            text_control (QLineEdit): the control where to take the sigma value
        """
        gauss_filter = list(self.image.gauss_filter)
        gauss_filter[1] = float(text_control.text())
        self.image.gauss_filter = tuple(gauss_filter)
        self.defaults.gauss_filter = tuple(gauss_filter)
        self.frames_panel.update_figure()

    def _set_gauss_toggle(self, text_control, toggle):
        """
        Enables the gaussian filter.

        Args:
            text_control (QLineEdit): the control where to take the sigma value
            toggle (bool): filter on/off
        """
        gauss_filter = list(self.image.gauss_filter)
        gauss_filter[0] = bool(toggle)
        self.image.gauss_filter = tuple(gauss_filter)
        self.defaults.gauss_filter = tuple(gauss_filter)
        self.frames_panel.update_figure()
        text_control.setEnabled(toggle)

    def _on_frames_click(self, event):
        """
        Called by the mouse click event on the frames panel.
        """
        #store first coordinates if not in pan mode
        if not self.frame_status.pan:
            self.frames_panel.coords0 = (event.xdata, event.ydata)
            self.frames_panel.selections["current"].set_visible(True)
        else:
            self.frames_panel.coords0 = (None, None)

        self.frames_panel.coords1 = self.frames_panel.coords0

    def _on_frames_move(self, event):
        """
        Called when the mouse moves on the frames panel.
        """
        #first and current coordinates must be valid
        if None not in self.frames_panel.coords0 + (event.xdata, event.ydata)\
                                    and not self.frame_status.pan:
            #get the frame number of the first and current coordinates
            frame0, _, _ = self._get_coord_frame(self.frames_panel.coords0)
            frame1, _, _ = self._get_coord_frame((event.xdata, event.ydata))

            #if current coordinates are on the same frame update second coords
            if frame0 == frame1 and frame0 >= 0 and frame1 >= 0:
                self.frames_panel.coords1 = (event.xdata, event.ydata)
                self.frames_panel.update_current_sel()

    def _on_frames_release(self, event):
        """
        Called by the mouse release event on the frames panel.
        """
        #first check if all the coordinates are valid
        if None not in self.frames_panel.coords0 + self.frames_panel.coords1:
            frame_num, _, _ = self._get_coord_frame(self.frames_panel.coords1)

            #get coords relative to a single frame
            x01 = [
                int(self.frames_panel.coords0[0] % self.image.frame_w),
                int(self.frames_panel.coords1[0] % self.image.frame_w)
            ]
            y01 = [
                int(self.frames_panel.coords0[1] % self.image.frame_h),
                int(self.frames_panel.coords1[1] % self.image.frame_h)
            ]
            x01.sort()
            y01.sort()

            #check if the selection is null, and in that case add a minimum
            #1 pixel size
            if x01[0] == x01[1]:
                x01[1] += 1
                print "Warning: null horizontal selection correted to one-sized"
            if y01[0] == y01[1]:
                y01[1] += 1
                print "Warning: null vertical selection correted to one-sized"

            #invalidate stored coords
            self.frames_panel.coords0 = self.frames_panel.coords1 = (None,
                                                                     None)

            #delete (by setting it to null size) rectangle of current selection
            if not self.frame_status.pan:
                self.frames_panel.selections["current"].set_visible(False)

            #update respective slices
            if self.frame_status.min:
                self.image.background_slices = (slice(*y01), slice(*x01))
                self.defaults.slices_bkg = self.image.background_slices

            if self.frame_status.max:
                self.image.maximum_slices = (slice(*y01), slice(*x01))
                self.defaults.slices_max = self.image.maximum_slices

            if self.frame_status.main:
                self.image.main_slices = (slice(*y01), slice(*x01))
                self.defaults.slices_main = self.image.main_slices

            #renormalize
            if self.frame_status.max or self.frame_status.min:
                #vlim must be updated
                self.image.vlim_img = (None, None)
                self.image.vlim_img_orig = (None, None)
                self.frames_panel.update_figure()

            #pick coordinates
            if self.frame_status.pick or self.frame_status.pick_multi:

                m_x = (x01[0] + x01[1]) / 2.0
                m_y = (y01[0] + y01[1]) / 2.0
                wid = abs(x01[0] - x01[1])
                hei = abs(y01[0] - y01[1])

                pick_keys = ["pick_x", "pick_y", "pick_w", "pick_h"]
                pick_values = [m_x, m_y, wid, hei]
                self.image.results.set_pick(frame_num, pick_keys,
                                            dict(zip(pick_keys, pick_values)))

                message = 'Coordinates: (%.1f, %.1f)' % (m_x, m_y)
                message += ' - Width: %d, Height: %d' % (wid, hei)
                self.status_bar.showMessage(message)

                #update results window if needed
                self.show_results(new_window=False)

            #finally restore pan mode
            if not self.frame_status.pan:
                self.frames_panel.update_areas()
                if not self.frame_status.pick_multi:
                    self._set_pan_frames()

    def _on_filter_click(self, event):
        """
        Called by the mouse click event on the filter panel.
        """
        if self.filter_status.filter:
            self.filter_panel.coords0 = (event.xdata, event.ydata)
            self.filter_panel.selections["current"].set_visible(True)
        else:
            self.filter_panel.coords0 = (None, None)
        self.filter_panel.coords1 = self.filter_panel.coords0

    def _on_filter_move(self, event):
        """
        Called when the mouse moves on the filter panel.
        """
        #first and current coordinates must be valid
        if None not in self.filter_panel.coords0 + (event.xdata, event.ydata)\
                                    and not self.filter_status.pan:

            self.filter_panel.coords1 = (event.xdata, event.ydata)
            self.filter_panel.update_current_sel()

    def _on_filter_release(self, event):
        """
        Called by the mouse release event on the filter panel.
        """
        if None not in self.filter_panel.coords0 + self.filter_panel.coords1:

            x01 = [self.filter_panel.coords0[0], self.filter_panel.coords1[0]]
            y01 = [self.filter_panel.coords0[1], self.filter_panel.coords1[1]]
            x01.sort()
            y01.sort()

            if x01[0] == x01[1]:
                print "Warning: null horizontal selection"
            if y01[0] == y01[1]:
                print "Warning: null vertical selection"

            if self.filter_status.filter:
                #reset the selection circle
                self.filter_panel.selections["current"].set_visible(False)
                self.image.filter_points_list.append(FilterPoint())
                self.image.filter_points_list[-1].\
                                set_from_coords(x01[0], y01[0], x01[1], y01[1])
                self.update_plots()

            #invalidate stored coords
            self.filter_panel.coords0 = self.filter_panel.coords1 = (None,
                                                                     None)

    def _test_frames_vlim(self, vlim):
        """
        Returns the validity of frames colorscale with the given correction.
        If valid the colorscale is update in the image class.

        Args:
            vlim (tuple): floats of the corrections to the colorscale
        """
        test_min, test_max = self.image.get_vlim_img(corr=vlim)
        test_min_orig, test_max_orig = self.image.get_vlim_img_orig(corr=vlim)

        test_cond = test_max > test_min and test_max_orig > test_min_orig

        if test_cond:
            self.image.vlim_img_corr = vlim
            self.defaults.vlim_img_corr = vlim
            self.frames_panel.update_figure(update_img=False)

        return test_cond

    def _test_fft_vlim(self, vlim):
        """
        Returns the validity of fft colorscale with the given correction.
        If valid the colorscale is update in the image class.

        Args:
            vlim (tuple): floats of the corrections to the colorscale
        """
        test_min, test_max = self.image.get_vlim_fft(corr=vlim)

        test_cond = test_max > test_min

        if test_cond:
            self.image.vlim_fft_corr = vlim
            self.defaults.vlim_fft_corr = vlim
            self.filter_panel.update_figure(update_img=False)

        return test_cond

    def _update_fft_frame_menu(self):
        """
        Initializes the menu that selects the frame to show in the fft filter
        panel.
        """
        self.fft_frame_menu.clear()
        fft_frames = QtGui.QActionGroup(self)

        selections = [-2, -1] + list(self.image.valid_frames_id)

        #if the default frame is no more present set the average as preselected
        if self.defaults.fft_frame_n in selections:
            active = self.defaults.fft_frame_n
        else:
            active = -1

        for frame_n in selections:
            #"no frame" and "average frame" are codified in the ImageLab class,
            #other frames are codified by their id
            if frame_n == -2:
                name = "None"
            elif frame_n == -1:
                name = "Average"
            else:
                name = str(frame_n)
            act = QtGui.QAction(name, self)
            act.triggered.connect(partial(self._select_fft_frame, frame_n))
            act.setCheckable(True)
            if frame_n == active:
                act.setChecked(True)
            fft_frames.addAction(act)

        self.fft_frame_menu.addActions(fft_frames.actions())

    def _select_fft_frame(self, num):
        """
        Selects the frame number for the fft panel visualization.

        Args:
            num (int): the number of the frame selected
        """
        num = int(num)
        if num != self.image.fft_frame_num:
            self.image.fft_frame_num = num
            self.defaults.fft_frame_n = num

            #invalidate current fft frame and renormalize
            self.image.fft_frame = None
            self.image.vlim_fft = (None, None)
            self.filter_panel.update_figure()

    def _filter_reset(self):
        """
        Resets the  fft filter deleting all the mask.
        """
        self.image.filter_points_list = []
        self.update_plots()

    def _filter_cancel_last(self):
        """
        Deletes just the last mask point inserted in the fft filter.
        """
        self.image.filter_points_list = self.image.filter_points_list[0:-1]
        self.update_plots()
Esempio n. 21
0
class Window(QtGui.QWidget):
    # G2 = nil

    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure)

        self.toolbar = NavigationToolbar(self.canvas, self)
        # self.toolbar.hide()

        # Just some button
        self.button = QtGui.QPushButton('Plot')
        self.button.clicked.connect(self.plot)

        self.button1 = QtGui.QPushButton('Zoom')
        self.button1.clicked.connect(self.zoom)

        self.button2 = QtGui.QPushButton('Pan')
        self.button2.clicked.connect(self.pan)

        self.button3 = QtGui.QPushButton('Home')
        self.button3.clicked.connect(self.home)

        self.button4 = QtGui.QPushButton('Home')
        self.button3.clicked.connect(self.home)
        # tabs = QtGui.QTabWidget()
        # tab1 = QtGui.QWidget()
        # tab2 = QtGui.QWidget()

        # set the layout
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)
        layout.addWidget(self.button)
        layout.addWidget(self.button1)
        layout.addWidget(self.button2)
        layout.addWidget(self.button3)

        self.setLayout(layout)

    def home(self):
        self.toolbar.home()

    def zoom(self):
        self.toolbar.zoom()

    def pan(self):
        self.toolbar.pan()

    def addData(self, G=None):
        self.G2

    def plot(self):
        ''' plot some random stuff '''
        squarify.plot(sizes=[13, 22, 35, 5],
                      label=["group A", "group B", "group C", "group D"],
                      alpha=.7)
        # plt.axis('off')
        # plt.show()
        # data = [random.random() for i in range(25)]
        # ax = self.figure.add_subplot(111)
        # ax.hold(False)
        # ax.plot(data, '*-')
        self.canvas.draw()

    def addData(self, G=None):
        G2 = G
        print("G2 is ->", G2)