Esempio n. 1
0
class MainWindow(QtWidgets.QMainWindow):
    """The only window of the application."""
    def __init__(self, settings):
        super(MainWindow, self).__init__()
        self.settings = settings

        self.setupUi()

        self.dock_area = DockArea()
        self.setCentralWidget(self.dock_area)

        self.createDocks()

        self.loadSettings()
        self.setWindowTitle('Rb Lock')

    def setupUi(self):
        pass

    def createDocks(self):
        self.rb_lock_widget = RbLockWidget(self.settings, self)
        self.rb_lock_widget_dock = Dock('Rb Lock', widget=self.rb_lock_widget)
        self.dock_area.addDock(self.rb_lock_widget_dock)

    def loadSettings(self):
        """Load window state from self.settings"""

        self.settings.beginGroup('mainwindow')
        geometry = self.settings.value('geometry')
        state = self.settings.value('windowstate')
        dock_string = str(self.settings.value('dockstate'))
        if dock_string is not "":
            dock_state = eval(dock_string)
            self.dock_area.restoreState(dock_state)
        self.settings.endGroup()

        self.restoreGeometry(geometry)
        self.restoreState(state)

    def saveSettings(self):
        """Save window state to self.settings."""
        self.settings.beginGroup('mainwindow')
        self.settings.setValue('geometry', self.saveGeometry())
        self.settings.setValue('windowstate', self.saveState())
        dock_state = self.dock_area.saveState()
        # dock_state returned here is a python dictionary. Coundn't find a good
        # way to save dicts in QSettings, hence just using representation
        # of it.
        self.settings.setValue('dockstate', repr(dock_state))
        self.settings.endGroup()

    def closeEvent(self, event):
        self.rb_lock_widget.saveSettings()
        self.saveSettings()
Esempio n. 2
0
class MainWindow(QMainWindow, Ui_MainWindow):
    """The only window of the application."""

    def __init__(self, settings):
        super(MainWindow, self).__init__()
        self.settings = settings

        self.setupUi(self)

        self.dock_area = DockArea()
        self.setCentralWidget(self.dock_area)

        self.createDocks()

        self.loadSettings()

    def createDocks(self):
        self.zmq_subscriber = ZMQSubscriber(self.settings, self)
        self.zmq_subscriber_dock = Dock('Subscriber',
                                        widget=self.zmq_subscriber)
        self.dock_area.addDock(self.zmq_subscriber_dock)

    def loadSettings(self):
        """Load window state from self.settings"""

        self.settings.beginGroup('mainwindow')
        geometry = self.settings.value('geometry').toByteArray()
        state = self.settings.value('windowstate').toByteArray()
        dock_string = str(self.settings.value('dockstate').toString())
        if dock_string is not "":
            dock_state = eval(dock_string)
            self.dock_area.restoreState(dock_state)
        self.settings.endGroup()

        self.restoreGeometry(geometry)
        self.restoreState(state)

    def saveSettings(self):
        """Save window state to self.settings."""
        self.settings.beginGroup('mainwindow')
        self.settings.setValue('geometry', self.saveGeometry())
        self.settings.setValue('windowstate', self.saveState())
        dock_state = self.dock_area.saveState()
        # dock_state returned here is a python dictionary. Coundn't find a good
        # way to save dicts in QSettings, hence just using representation
        # of it.
        self.settings.setValue('dockstate', repr(dock_state))
        self.settings.endGroup()

    def closeEvent(self, event):
        self.zmq_subscriber.saveSettings()
        self.saveSettings()
Esempio n. 3
0
class AWGOptimizer(Form, Base):
    def __init__(self, deviceClass, config, parent=None):
        Base.__init__(self, parent)
        Form.__init__(self)
        Form.setupUi(self, self)
        self.config = config
        self.configname = "AWGOptimizer"
        self.setWindowTitle("AWG Optimizer")
        guiState = self.config.get(self.configname + ".guiState")
        state = self.config.get(self.configname + '.state')
        pos = self.config.get(self.configname + '.pos')
        size = self.config.get(self.configname + '.size')
        isMaximized = self.config.get(self.configname + '.isMaximized')
        restoreGuiState(self, self.config.get(self.configname + ".guiState"))
        if state: self.restoreState(state)
        if pos: self.move(pos)
        if size: self.resize(size)
        if isMaximized: self.showMaximized()

        self.show()
        self.awgUi = AWGUi(deviceClass, config, dict())
        self.awgUi.setupUi(self.awgUi)
        self.splitter.insertWidget(1, self.awgUi)

        #oscilloscope plot window
        name = "Oscilloscope Trace"
        self.scopeDock = Dock(name)
        self.scopePlot = CoordinatePlotWidget(self, name=name)
        self.scopeView = self.scopePlot._graphicsView
        self.scopeDock.addWidget(self.scopePlot)
        self.area = DockArea()
        self.area.addDock(self.scopeDock)
        self.plotDict = {
            name: {
                "dock": self.scopeDock,
                "widget": self.scopePlot,
                "view": self.scopeView
            }
        }
        self.verticalLayout.insertWidget(0, self.area)

        #trace ui
        self.penicons = pens.penicons().penicons()
        self.traceui = Traceui.Traceui(self.penicons,
                                       self.config,
                                       self.configname,
                                       self.plotDict,
                                       hasMeasurementLog=False,
                                       highlightUnsaved=False)
        self.traceui.setupUi(self.traceui)
        traceDock = Dock("Traces")
        traceDock.addWidget(self.traceui)
        self.area.addDock(traceDock, 'left')
        self.device = self.awgUi.device

        self.measureWaveformButton.clicked.connect(self.onMeasureWaveform)
        self.optimizeButton.clicked.connect(self.onOptimize)

        dockAreaState = self.config.get(self.configname + '.dockAreaState')
        try:
            if dockAreaState: self.area.restoreState(dockAreaState)
        except Exception as e:
            print(e)

    def saveConfig(self):
        self.config[self.configname + ".guiState"] = saveGuiState(self)
        self.config[self.configname + '.state'] = self.saveState()
        self.config[self.configname + '.pos'] = self.pos()
        self.config[self.configname + '.size'] = self.size()
        self.config[self.configname + '.isMaximized'] = self.isMaximized()
        self.config[self.configname + '.dockAreaState'] = self.area.saveState()
        self.awgUi.saveConfig()

    def closeEvent(self, e):
        self.saveConfig()

    def onMeasureWaveform(self):
        pass

    def onOptimize(self):
        pass
Esempio n. 4
0
class DockAreaTabWidgetBase(QtGui.QWidget):
    
    def __init__(self, *args, **kwargs):
        self.main = kwargs.pop("main")
        tabName = kwargs.pop("tabName")
        QtGui.QWidget.__init__(self, *args, **kwargs)
        self.setObjectName(tabName)
        self._layout = QtGui.QGridLayout(self)
            
    def _InitDocks(self):
        
        # Define docking area
        if hasattr(self, "_dockArea"):
            self._dockArea.setParent(None)
        self._dockArea = DockArea()

        self._plotDocks = self._defaultDockPos.keys()
        
        # Add dock to area
        for dock, pos in self._defaultDockPos.iteritems():
            self._dockArea.addDock(dock, *pos)
        
        self._layout.addWidget(self._dockArea, 0, 0, 1, 1)
    
    def Shown(self):
        self.DrawFrame()
    
    def DrawFrame(self, clear = True):   
        if clear:
            self.ClearPlots()
            
        for dock in self._plotDocks:
            if not dock.automaticDraw:
                continue
            dock.DrawPlot()
        
    def ClearPlots(self):
        for dock in self._plotDocks:
            if not dock.automaticDraw:
                continue
            dock.ClearPlot()
            
    def AutoscalePlots(self):
        for dock in self._plotDocks:
            if not dock.automaticDraw:
                continue
            dock.Autoscale()
            
    def SaveState(self):
        res = {}
        res["dockingState"] = self._dockArea.saveState()
        for dock in self._plotDocks:
            res["dock_" + dock.name()] = dock.SaveState()
        return res
    
    def SetState(self, state):
        try:    
            if "dockingState" in state:
                self._dockArea.restoreState(state["dockingState"])           
        except:
            print "Docking area restore failed, restoring defaults:"
            traceback.print_exc()
            print "Restore defaults"
            self._InitDocks()
 
        for dock in self._plotDocks:
            stateName = "dock_" + dock.name()
            if stateName in state:
                dock.SetState(state[stateName])
Esempio n. 5
0
class MainWindow(QtGui.QMainWindow):
    # for dock
    def __init__(self, parent=None):

        from pyqtgraph import exporters
        exporters.Exporter.register = self.modified_register

        QtGui.QMainWindow.__init__(self, parent)

        self.setWindowIcon(QtGui.QIcon(logo))
        self.setWindowTitle('CIVET')

        self.setGeometry(200, 143, 1574, 740)
        pg.setConfigOption('background', QtGui.QColor(215, 214, 213, 255))
        pg.setConfigOption('foreground', 'k')
        palette = QtGui.QPalette()
        palette.setColor(QtGui.QPalette.Background,
                         QtGui.QColor(215, 214, 213, 255))
        self.setPalette(palette)

        self.mainframe = QtGui.QFrame()

        self.copen = 0
        self.sopen = 0
        self.ropen = 0
        self.gridstate = 0
        self.current_docks = []

        self.loadaction = QtGui.QAction("&Open", self)
        self.loadaction.setShortcut("Ctrl+O")
        self.loadaction.setStatusTip("Open File")
        self.loadaction.triggered.connect(self.loaddata)

        self.exportaction = QtGui.QAction("&Export", self)
        self.exportaction.setShortcut("Ctrl+E")
        self.exportaction.setStatusTip("Export to a folder")
        self.exportaction.triggered.connect(self.exportdata)

        self.viewaction1 = QtGui.QAction("&Grid View 1", self)
        self.viewaction1.setStatusTip("Grid View 1")
        self.viewaction1.triggered.connect(self.grid_view_1)

        self.viewaction2 = QtGui.QAction("&Grid View 2", self)
        self.viewaction2.setStatusTip("Grid View 2")
        self.viewaction2.triggered.connect(self.grid_view_2)

        self.about = QtGui.QAction("&Info", self)
        self.about.setStatusTip("Info")
        self.about.triggered.connect(self.about_info)

        self.mainMenu = self.menuBar()
        self.fileMenu = self.mainMenu.addMenu("&File")
        self.fileMenu.addAction(self.loadaction)
        self.fileMenu.addAction(self.exportaction)

        self.viewMenu = self.mainMenu.addMenu("&Display")
        self.viewMenu.addAction(self.viewaction1)
        self.viewMenu.addAction(self.viewaction2)

        self.aboutMenu = self.mainMenu.addMenu("&About")
        self.aboutMenu.addAction(self.about)

        self.maketoolbar()

        self.area = DockArea()

        self.drho = Dock("\u03c1")
        self.dlamb = Dock("\u03bb")
        self.dalpha = Dock("\u03b1")
        self.dbeta = Dock("\u03b2")
        self.dphase = Dock("Phase")
        self.dcontrols = Dock("Controls")

        self.layout = QtGui.QHBoxLayout()
        self.layout.addWidget(self.area)
        self.mainframe.setLayout(self.layout)
        self.mainframe.setFrameStyle(QtGui.QFrame.Box | QtGui.QFrame.Raised)
        self.mainframe.setLineWidth(8)

# all those have different relative positions so made bunch of functions, not one.

    def modified_register(self, cls):

        exporters.Exporter.Exporters.append(None)

    def dlambadd(self):
        try:
            self.area.addDock(self.dlamb, 'bottom', self.drho)
        except:
            try:
                self.area.addDock(self.dlamb, 'left', self.dphase)
            except:
                self.area.addDock(self.dlamb, 'left')

    def drhoadd(self):
        try:
            self.area.addDock(self.drho, 'top', self.dlamb)
        except:
            try:
                self.area.addDock(self.drho, 'left', self.dalpha)
            except:
                self.area.addDock(self.drho, 'left')

    def dalphaadd(self):
        try:
            self.area.addDock(self.dalpha, 'left', self.dbeta)
        except:
            try:
                self.area.addDock(self.dalpha, 'right', self.drho)
            except:
                try:
                    self.area.addDock(self.dalpha, 'top', self.dphase)
                except:
                    self.area.addDock(self.dalpha, 'left')

    def dbetaadd(self):
        try:
            self.area.addDock(self.dbeta, 'top', self.dcontrols)
        except:
            try:
                self.area.addDock(self.dbeta, 'right', self.dalpha)
            except:
                self.area.addDock(self.dbeta, 'right')

    def dphaseadd(self):
        try:
            self.area.addDock(self.dphase, 'left', self.dcontrols)
        except:
            try:
                self.area.addDock(self.dphase, 'bottom', self.dalpha)
            except:
                try:
                    self.area.addDock(self.dphase, 'right', self.dlamb)
                except:
                    self.area.addDock(self.drho, 'bottom')

    def dcontrolsadd(self):
        try:
            self.area.addDock(self.dcontrols, 'right', self.dphase)
        except:
            try:
                self.area.addDock(self.dcontrols, 'bottom', self.dbeta)
            except:
                self.area.addDock(self.dcontrols, 'right')

    def checkbox_init(self):
        self.dock_on = []

        self.cwindow = QtGui.QMainWindow()
        self.cwindow.setWindowIcon(QtGui.QIcon(logo))
        self.cwindow.setWindowTitle('Plots')

        self.boxeswidget = QtGui.QWidget(self.cwindow)
        checkbox_layout = QtGui.QGridLayout(self.boxeswidget)
        self.ch_lamb = QtGui.QCheckBox(self.boxeswidget)
        self.ch_lamb.setText('\u03bb')
        self.ch_lamb.setChecked(True)
        self.ch_lamb.stateChanged.connect(lambda: self.dlamb.close(
        ) if not self.ch_lamb.isChecked() else self.dlambadd())

        self.ch_rho = QtGui.QCheckBox(self.boxeswidget)
        self.ch_rho.setText('\u03c1')
        self.ch_rho.setChecked(True)
        self.ch_rho.stateChanged.connect(lambda: self.drho.close(
        ) if not self.ch_rho.isChecked() else self.drhoadd())

        self.ch_alpha = QtGui.QCheckBox(self.boxeswidget)
        self.ch_alpha.setText('\u03b1')
        self.ch_alpha.setChecked(True)
        self.ch_alpha.stateChanged.connect(lambda: self.dalpha.close(
        ) if not self.ch_alpha.isChecked() else self.dalphaadd())

        self.ch_beta = QtGui.QCheckBox(self.boxeswidget)
        self.ch_beta.setText('\u03b2')
        self.ch_beta.setChecked(True)
        self.ch_beta.stateChanged.connect(lambda: self.dbeta.close(
        ) if not self.ch_beta.isChecked() else self.dbetaadd())

        self.ch_phase = QtGui.QCheckBox(self.boxeswidget)
        self.ch_phase.setText('Phase')
        self.ch_phase.setChecked(True)
        self.ch_phase.stateChanged.connect(lambda: self.dphase.close(
        ) if not self.ch_phase.isChecked() else self.dphaseadd())

        self.ch_controls = QtGui.QCheckBox(self.boxeswidget)
        self.ch_controls.setText('Controls')
        self.ch_controls.setChecked(True)
        self.ch_controls.stateChanged.connect(lambda: self.dcontrols.close(
        ) if not self.ch_controls.isChecked() else self.dcontrolsadd())

        checkbox_layout.addWidget(self.ch_rho, 0, 0, 1, 1)
        checkbox_layout.addWidget(self.ch_lamb, 1, 0, 1, 1)
        checkbox_layout.addWidget(self.ch_alpha, 0, 1, 1, 1)
        checkbox_layout.addWidget(self.ch_phase, 1, 1, 1, 1)
        checkbox_layout.addWidget(self.ch_beta, 0, 2, 1, 1)
        checkbox_layout.addWidget(self.ch_controls, 1, 2, 1, 1)
        self.cwindow.setCentralWidget(self.boxeswidget)

    def checkbox(self):
        if self.copen == 0:
            self.check_current_docks()
            self.closed_docks = []

            for i in self.docklist:
                if i not in self.current_docks:
                    self.closed_docks += [i]
            for i in self.closed_docks:
                eval(i[:5] + "ch_" + i[6:]).setChecked(False)

            self.cwindow.show()
            self.copen = 1
        else:
            self.cwindow.hide()
            self.copen = 0

    def about_info(self):

        self.awindow = QtGui.QMainWindow()
        self.awindow.setWindowIcon(QtGui.QIcon(logo))
        self.awindow.setWindowTitle('About')
        labels = QtGui.QWidget(self.awindow)
        labels_layout = QtGui.QVBoxLayout(labels)
        self.line0 = QtGui.QLabel()
        self.line1 = QtGui.QLabel(
            "CIVET: Current Inspired Visualization and Evaluation of the")
        self.line2 = QtGui.QLabel()
        self.line3 = QtGui.QLabel(
            "Totally asymmetric simple exclusion process (TASEP)")
        self.line4 = QtGui.QLabel()
        self.line5 = QtGui.QLabel("Copyright (c) 2018,")
        self.line6 = QtGui.QLabel()
        self.line7 = QtGui.QLabel(
            "Wonjun Son, Dan D. Erdmann-Pham,  Khanh Dao Duc, Yun S. Song")
        self.line8 = QtGui.QLabel()
        self.line9 = QtGui.QLabel("All rights reserved.")
        self.line10 = QtGui.QLabel()

        for i in range(11):
            eval("self.line" + str(i)).setAlignment(QtCore.Qt.AlignCenter)
            labels_layout.addWidget(eval("self.line" + str(i)))
        self.awindow.setCentralWidget(labels)
        self.awindow.show()

    def exportdata(self):

        self.dialog = QtGui.QFileDialog()
        self.dialog.setOption(QtGui.QFileDialog.ShowDirsOnly)
        self.dialog.setFileMode(QtGui.QFileDialog.DirectoryOnly)

        folder_name = self.dialog.getSaveFileName(self, "Save Directory")
        filepath = os.path.join(os.path.abspath(os.sep), folder_name)
        if not os.path.exists(filepath):
            makedirs(filepath)

        # arr = QtCore.QByteArray()
        # buf = QtCore.QBuffer(arr)
        # svg = QtSvg.QSvgGenerator()
        # svg.setOutputDevice(buf)
        # dpi = QtGui.QDesktopWidget().physicalDpiX()
        # svg.setResolution(dpi)

        svg = QtSvg.QSvgGenerator()
        svg.setFileName("hh")
        svg.setSize(QtCore.QSize(2000, 2000))
        svg.setViewBox(self.rect())
        svg.setTitle("SVG svg Example Drawing")
        svg.setDescription("An SVG drawing created by the SVG Generator ")

        p = QtGui.QPainter()
        p.begin(svg)
        try:
            self.render(p)
        finally:
            p.end()
        # gen.setViewBox(QtGui.QRect(0, 0, 200, 200));
        # gen.setTitle(tr("SVG Gen Example Drawing"));
        # gen.setDescription(tr("An SVG drawing created by the SVG Generator ""Example provided with Qt."));

        lambda_data = os.path.join(filepath, "Lambda_data.csv")
        with open(lambda_data, "w") as output:
            try:
                writer = csv.writer(output, lineterminator='\n')
                for val in np.array(glo_var.lambdas)[:, 1]:
                    writer.writerow([val])
            except:
                pass

        summary = os.path.join(filepath, "Summary.csv")
        with open(summary, "w") as output:
            try:
                writer = csv.writer(output,
                                    delimiter='\t',
                                    lineterminator='\n')
                writer.writerow(["alpha", glo_var.alpha])
                writer.writerow(["beta", glo_var.beta])
                writer.writerow(["l", glo_var.l])
                writer.writerow(["Phase", self.phas.pointer.region_aft])
            except:
                pass

        # for name, pitem in self.pltlist:
        # 	self.exportimg(pitem,os.path.join(filepath,name + ".svg"))
        # 	# self.exportimg(pitem,os.path.join(filepath,name + ".png"))

        currentanddensity = os.path.join(filepath, "Current & Density.csv")
        with open(currentanddensity, "w") as output:
            writer = csv.writer(output, delimiter='\t', lineterminator='\n')
            # combine alpha, beta    pre and post. Do it here to lessen the computation
            alpha_x_data = np.concatenate([
                np.array(self.jalph.alphas_pre),
                np.linspace(self.jalph.trans_point, 1, 2)
            ])
            alpha_j_data = np.concatenate(
                [self.jalph.j_l_values,
                 np.array([self.jalph.jpost] * 2)])
            alpha_rho_data = np.array(self.jalph.rho_avg_pre +
                                      self.jalph.rho_avg_post)

            beta_x_data = np.concatenate([
                np.array(self.jbet.betas_pre),
                np.linspace(self.jbet.trans_point, 1, 2)
            ])
            beta_j_data = np.concatenate(
                [self.jbet.j_r_values,
                 np.array([self.jbet.jpost] * 2)])
            beta_rho_data = np.array(self.jbet.rho_avg_pre +
                                     self.jbet.rho_avg_post)

            alpha_data = np.vstack(
                [alpha_x_data, alpha_j_data, alpha_rho_data])
            beta_data = np.vstack([beta_x_data, beta_j_data, beta_rho_data])

            writer.writerow([
                "alpha", "Current", "Average Density", '\t', '\t', "beta",
                "Current", "Average Density"
            ])
            for i in range(len(alpha_x_data)):
                writer.writerow(
                    list(alpha_data[:, i]) + [''] * 2 + list(beta_data[:, i]))
            writer.writerow('\n')
            writer.writerow(
                ['beta', glo_var.beta, '', '', '', 'alpha', glo_var.alpha, ''])
            writer.writerow([
                'transition point', self.jalph.trans_point, '', '', '',
                'transition point', self.jbet.trans_point, ''
            ])

        self.pdfgroup1 = ['Lambda_fig', 'Density_fig']
        self.pdfgroup2 = ['Current_alpha_fig', 'Current_beta_fig']

        for name, pitem in self.pltlist:
            # self.exportimg(pitem,os.path.join(filepath,name + ".png"))
            path = os.path.join(filepath, name + ".svg")
            #			if name == 'Current_alpha_fig':
            #				self.jalph.p3.setLabel('right',"\u2329\u03c1 \u232a",**glo_var.labelstyle)
            #				self.jalph.p3main.plotItem.legend.items=[]
            #				self.jalph.p3.plot(pen=self.jalph.jpen, name='J')
            #				self.jalph.p3.plot(pen=self.jalph.rho_dash, name='\u2329\u03c1 \u232a')

            #			elif name == 'Current_beta_fig':
            #				self.jbet.p4.setLabel('right',"\u2329\u03c1 \u232a",**glo_var.labelstyle)
            #				self.jbet.p4main.plotItem.legend.items=[]
            #				self.jbet.p4.plot(pen=self.jbet.jpen, name='J')
            #				self.jbet.p4.plot(pen=self.jbet.rho_dash, name='\u2329\u03c1 \u232a')
            self.exportimg(pitem, path)

            if name in self.pdfgroup1:
                self.makepdf(path, os.path.join(filepath, name + ".pdf"), 500,
                             260, 20, 240)
            elif name == 'Current_alpha_fig':
                self.makepdf(path, os.path.join(filepath, name + ".pdf"), 350,
                             280, 30, 230)
#				self.jalph.p3.setLabel('right',"\u2329 \u03c1 \u232a",**glo_var.labelstyle)
#				self.jalph.p3main.plotItem.legend.items=[]
#				self.jalph.p3.plot(pen=self.jalph.jpen, name='J')
#				self.jalph.p3.plot(pen=self.jalph.rho_dash, name='\u2329 \u03c1 \u232a')
            elif name == 'Current_beta_fig':
                self.makepdf(path, os.path.join(filepath, name + ".pdf"), 350,
                             280, 30, 230)


#				self.jbet.p4.setLabel('right',"\u2329 \u03c1 \u232a",**glo_var.labelstyle)
#				self.jbet.p4main.plotItem.legend.items=[]
#				self.jbet.p4.plot(pen=self.jbet.jpen, name='J')
#				self.jbet.p4.plot(pen=self.jbet.rho_dash, name='\u2329 \u03c1 \u232a')

            else:
                self.makepdf(path, os.path.join(filepath, name + ".pdf"), 410,
                             330, 10, 300)

            os.remove(path)

    def makepdf(self, path, name, x, y, z, q):

        from svglib.svglib import svg2rlg
        from reportlab.pdfgen import canvas
        from reportlab.graphics import renderPDF
        rlg = svg2rlg(path)
        rlg.scale(0.8, 0.8)
        c = canvas.Canvas(name)
        c.setPageSize((x, y))
        renderPDF.draw(rlg, c, z, q)
        c.showPage()
        c.save()

    def exportimg(self, img, path):
        # self.img = pg.exporters.ImageExporter(img)
        # self.img.export(path)
        self.svg = pg.exporters.SVGExporter(img)
        self.svg.export(fileName=path)

    def maketoolbar(self):
        self.state = None
        self.titlebarstate = 1
        self.toolbar = self.addToolBar("Toolbar")

        home = QtGui.QAction(
            QtGui.QIcon(QtGui.QApplication.style().standardIcon(
                QtGui.QStyle.SP_ComputerIcon)), 'Toggle Grid View', self)
        home.triggered.connect(self.toggle_grid_view)
        self.toolbar.addAction(home)

        fix = QtGui.QAction(
            QtGui.QIcon(QtGui.QApplication.style().standardIcon(
                QtGui.QStyle.SP_ArrowDown)), 'Fix current layout', self)
        fix.triggered.connect(self.fixdock)
        self.toolbar.addAction(fix)

        self.savedockandvaluesinit()
        save = QtGui.QAction(
            QtGui.QIcon(QtGui.QApplication.style().standardIcon(
                QtGui.QStyle.SP_FileDialogListView)), 'Save current layout',
            self)
        save.triggered.connect(self.popsavedockandvalues)
        self.toolbar.addAction(save)

        self.restoredockandvaluesinit()
        restore = QtGui.QAction(
            QtGui.QIcon(QtGui.QApplication.style().standardIcon(
                QtGui.QStyle.SP_BrowserReload)), 'Restore saved layout', self)
        restore.triggered.connect(self.poprestoredockandvalues)
        self.toolbar.addAction(restore)

        self.checkbox_init()
        checkbox = QtGui.QAction(
            QtGui.QIcon(QtGui.QApplication.style().standardIcon(
                QtGui.QStyle.SP_FileDialogDetailedView)),
            'Open & close specific windows', self)
        checkbox.triggered.connect(self.checkbox)
        self.toolbar.addAction(checkbox)

    def fixdock(self):
        if self.titlebarstate == 1:
            self.dlamb.hideTitleBar()
            self.drho.hideTitleBar()
            self.dalpha.hideTitleBar()
            self.dbeta.hideTitleBar()
            self.dcontrols.hideTitleBar()
            self.dphase.hideTitleBar()
            self.titlebarstate = 0

        else:
            self.dlamb.showTitleBar()
            self.drho.showTitleBar()
            self.dalpha.showTitleBar()
            self.dbeta.showTitleBar()
            self.dcontrols.showTitleBar()
            self.dphase.showTitleBar()
            self.titlebarstate = 1

    def savedockandvaluesinit(self):

        self.swindow = QtGui.QMainWindow()
        self.swindow.setWindowIcon(QtGui.QIcon(logo))
        self.swindow.setWindowTitle('Save')

        boxeswidget = QtGui.QWidget(self.swindow)
        checkbox_layout = QtGui.QGridLayout(boxeswidget)

        self.sa_dock = QtGui.QCheckBox(boxeswidget)
        self.sa_dock.setText('Grid View')
        self.sa_dock.setChecked(True)

        self.sa_values = QtGui.QCheckBox(boxeswidget)
        self.sa_values.setText('Values')
        self.sa_values.setChecked(True)

        self.save_button = QtGui.QPushButton('Save', self)
        self.save_button.clicked.connect(self.savedockandvalues)

        checkbox_layout.addWidget(self.sa_dock, 0, 0, 1, 1)
        checkbox_layout.addWidget(self.sa_values, 0, 1, 1, 1)
        checkbox_layout.addWidget(self.save_button, 1, 0, 1, 2)

        self.swindow.setCentralWidget(boxeswidget)

    def restoredockandvaluesinit(self):

        self.rwindow = QtGui.QMainWindow()
        self.rwindow.setWindowIcon(QtGui.QIcon(logo))
        self.rwindow.setWindowTitle('Restore')

        boxeswidget = QtGui.QWidget(self.rwindow)
        checkbox_layout = QtGui.QGridLayout(boxeswidget)

        self.re_dock = QtGui.QCheckBox(boxeswidget)
        self.re_dock.setText('Grid View')
        self.re_dock.setChecked(True)

        self.re_values = QtGui.QCheckBox(boxeswidget)
        self.re_values.setText('Values')
        self.re_values.setChecked(True)

        self.restore_button = QtGui.QPushButton('Restore', self)
        self.restore_button.clicked.connect(self.restoredockandvalues)

        checkbox_layout.addWidget(self.re_dock, 0, 0, 1, 1)
        checkbox_layout.addWidget(self.re_values, 0, 1, 1, 1)
        checkbox_layout.addWidget(self.restore_button, 1, 0, 1, 2)

        self.rwindow.setCentralWidget(boxeswidget)

    def savedockandvalues(self):
        if self.sa_values.checkState:
            self.savedlambdas = deepcopy(glo_var.lambdas)
            self.savedalpha = glo_var.alpha
            self.savedbeta = glo_var.beta
            self.savedl = glo_var.l
        if self.sa_dock.checkState:
            self.saved_state = []
            self.state = self.area.saveState()
            self.saved_state = self.check_current_docks()[:]

        self.sopen = 0
        self.swindow.hide()

    def popsavedockandvalues(self):
        if self.sopen == 0:
            self.swindow.show()
            self.sopen = 1

        else:
            self.swindow.hide()
            self.sopen = 0

    def poprestoredockandvalues(self):
        if self.ropen == 0:
            self.rwindow.show()
            self.ropen = 1

        else:
            self.rwindow.hide()
            self.ropen = 0

    def restoredockandvalues(self):
        if self.re_values.checkState:
            glo_var.lambdas = deepcopy(self.savedlambdas)
            glo_var.alpha = self.savedalpha
            glo_var.beta = self.savedbeta
            glo_var.l = self.savedl

            self.lamb_po.update()
            self.rh.update()
            self.phas.update()
            self.jalph.update()
            self.jbet.update()
            self.slid.update_alpha_slid(self.slid.ws[0])
            self.slid.update_beta_slid(self.slid.ws[1])
            self.slid.update_l_slid(self.slid.ws[2])

        if self.re_dock.checkState:

            if self.state != None:
                closed_docks = []
                self.check_current_docks()
                # Notice after below, current dock != real current dock. But it doesn't matter since we call check current dock every time.
                for i in self.current_docks:
                    if i not in self.saved_state:
                        eval(i).close()
                for i in self.saved_state:
                    if i not in self.current_docks:
                        eval(i + "add")()
                self.area.restoreState(self.state)
        self.ropen = 0
        self.rwindow.hide()

    def realinit(self):
        self.clear_buttons = [
            "self.lamb_po.p1main.coordinate_label.setText(\"\")",
            "self.rh.p2main.coordinate_label.setText(\"\")",
            "self.jalph.p3main.coordinate_label.setText(\"\")",
            "self.jbet.p4main.coordinate_label.setText(\"\")",
            "self.phas.p5main.coordinate_label.setText(\"\")"
        ]

        glo_var.pass_main(self)

        self.docklist = [
            'self.drho', 'self.dlamb', 'self.dalpha', 'self.dbeta',
            'self.dphase', 'self.dcontrols'
        ]
        self.area = DockArea()
        self.drho = Dock("Particle Density \u2374", closable=True)
        self.dlamb = Dock("Hopping Rate \u03bb", closable=True)
        self.dphase = Dock("Phase Diagram", closable=True)
        self.dcontrols = Dock("Controls", closable=True)
        self.dalpha = Dock(
            "Current J and average density \u27e8\u2374\u27e9 as a function of \u03b1",
            closable=True)
        self.dbeta = Dock(
            "Current J and average density \u27e8\u2374\u27e9 as a function of \u03b2",
            closable=True)

        self.layout = QtGui.QHBoxLayout()
        self.layout.addWidget(self.area)
        self.mainframe.setLayout(self.layout)
        self.mainframe.setFrameStyle(QtGui.QFrame.Box | QtGui.QFrame.Raised)
        self.mainframe.setLineWidth(8)

        pg.setConfigOptions(antialias=True)

        self.rh = rho.rho(self.drho)
        self.jalph = jalpha.jalpha(self.dalpha, self.rh)
        self.jbet = jbeta.jbeta(self.dbeta, self.rh)
        self.phas = phase.phase(self.dphase)
        self.lamb_po = lamb_pol.lamb_pol(self.dlamb)
        self.slid = slider.Widget(self.dcontrols, self.lamb_po, self.phas,
                                  self.rh, self.jbet, self.jalph)
        self.lamb_po.receive(self.slid)

        # default values to restore is input
        self.savedlambdas = glo_var.lambdas[:]
        self.savedalpha = glo_var.alpha
        self.savedbeta = glo_var.beta
        self.savedl = glo_var.l

        self.pltlist = [['Lambda_fig', self.lamb_po.p1],
                        ['Density_fig', self.rh.p2],
                        ['Current_alpha_fig', self.jalph.plotitemtoexport],
                        ['Current_beta_fig', self.jbet.plotitemtoexport],
                        ['Phase_fig', self.phas.p5]]

        self.grid_view_1()

        self.setCentralWidget(self.area)

        print(dir(self.area))
        print(self.area.childrenRect(), "childrenRect")
        print(self.area.contentsRect(), "contentesRect")
        print(self.area.rect())

    def check_current_docks(self):
        self.current_docks = []
        for i in self.docklist:
            if self.area.getContainer(eval(i)):
                self.current_docks += [i]
            else:
                pass
        return self.current_docks

    def toggle_grid_view(self):
        if self.gridstate == 0:
            self.grid_view_2()
            self.gridstate = 1
        else:
            self.grid_view_1()
            self.gridstate = 0

    def grid_view_1(self):
        for i in self.docklist:
            try:
                eval(i).close()
            except:
                pass

        self.drho.setMinimumSize(652, 370)
        self.dlamb.setMinimumSize(652, 370)
        self.dphase.setMinimumSize(487, 465)
        self.dcontrols.setMinimumSize(487, 275)
        self.dalpha.setMinimumSize(435, 370)
        self.dbeta.setMinimumSize(435, 370)

        self.area.addDock(self.drho, 'left')
        self.area.addDock(self.dlamb, 'bottom', self.drho)
        self.area.addDock(self.dphase, 'right')
        self.area.addDock(self.dcontrols, 'bottom', self.dphase)
        self.area.addDock(self.dalpha, 'right')
        self.area.addDock(self.dbeta, 'bottom', self.dalpha)

        self.drho.setMinimumSize(0, 0)
        self.dlamb.setMinimumSize(0, 0)
        self.dphase.setMinimumSize(0, 0)
        self.dcontrols.setMinimumSize(0, 0)
        self.dalpha.setMinimumSize(0, 0)
        self.dbeta.setMinimumSize(0, 0)

    def grid_view_2(self):
        for i in self.docklist:
            try:
                eval(i).close()
            except:
                pass
        self.area.addDock(self.drho, 'top')
        self.area.addDock(self.dlamb, 'bottom', self.drho)
        self.area.addDock(self.dphase, 'bottom')
        self.area.addDock(self.dcontrols, 'left', self.dphase)
        self.area.addDock(self.dalpha, 'right')
        self.area.addDock(self.dbeta, 'bottom', self.dalpha)

    def opengraphs(self):
        self.mn = main.main_class(app)
        self.window.hide()

    def loaddata(self):
        name = QtGui.QFileDialog.getOpenFileName(self, 'Open File', '.',
                                                 'text (*.txt *.csv)')
        if name == "":
            pass
        else:
            self.read_file(name)
            self.realinit()

    def read_file(self, input):
        global ison
        temp = []
        if ison == 0:
            ison = 1
        else:
            self.setCentralWidget(None)
            glo_var.initialize()

        if input[-3:] == 'csv':
            with open(input, newline='') as csvfile:
                spamreader = csv.reader(csvfile, delimiter=',', quotechar='|')
                lis = []
                for j in spamreader:
                    lis += j
                num_of_inputs = len(lis)
                glo_var.lambdas_degree = num_of_inputs
                for i in range(num_of_inputs):
                    glo_var.lambdas += [[
                        i / (num_of_inputs - 1),
                        round(eval(lis[i]), 2)
                    ]]
            glo_var.alpha = 0.04
            glo_var.beta = 0.04
            glo_var.l = 1

        elif input[-3:] == 'txt':
            f = open(input, 'r')
            # Breaks the loop i
            try:
                temp = []
                while (True):
                    T = f.readline().strip()
                    temp += [[glo_var.lambdas_degree, round(eval(T), 2)]]
            except:
                for x, y in temp:
                    glo_var.lambdas += [[x / (glo_var.lambdas_degree - 1), y]]
            glo_var.l = 1

        else:
            err = QtGui.QMessageBox(self.win)
            err.setIcon(QMessageBox().Warning)
            err.setText("Please select txt or csv file Format")
            err.setWindowTitle("File Format Error")
            err.setStandardButtons(QMessageBox.Ok)
            err.buttonClicked.connect()

    def eventFilter(self, source, event):
        if event.type() == QtCore.QEvent.MouseMove:
            if event.buttons() == QtCore.Qt.NoButton:
                pos = event.pos()
                if self.toolbar.rect().contains(
                        pos) or not self.area.rect().contains(pos):
                    self.clear_points()
            else:
                pass
        return QtGui.QMainWindow.eventFilter(self, source, event)

    def clear_points(self, exclude=None):
        if not exclude:
            for x in self.clear_buttons:
                eval(x)
        else:
            for x in self.clear_buttons[:exclude -
                                        1] + self.clear_buttons[exclude:]:
                eval(x)
Esempio n. 6
0
class MainWindow(QMainWindow, Ui_MainWindow):
    """Where all the action happens."""

    def __init__(self, settings):
        super(MainWindow, self).__init__()
        self.settings = settings
        self.setupUi(self)

        # MainWindow is a collection of widgets in their respective docks.
        # We make DockArea our central widget
        self.dock_area = DockArea()
        self.setCentralWidget(self.dock_area)

        self.createDocks()
        self.initAfterCreatingDockWidgets()
        self.loadSettings()

        self.connectSignalsToSlots()

        # all signals in place, send out the first image
        # self.image_browser.populateAndEmitImageInfo()
        self.image_browser.initialEmit()
        self.roi_editor_h.initialEmit()
        self.roi_editor_v.initialEmit()
        self.roi_editor_int.initialEmit()
        self.roi_editor_err.initialEmit()

        self.loadPlugins()

    def loadPlugins(self):
        """Looks for all plugins and creates menu entries, signals and
           slots for them."""
        self.pluginSignalMapper = QSignalMapper(self)
        for p in plugin_list:
            click_action = QAction(p.name, self)
            self.menuPlugins.addAction(click_action)
            self.connect(click_action, SIGNAL("triggered()"),
                         self.pluginSignalMapper, SLOT("map()"))
            self.pluginSignalMapper.setMapping(click_action, QString(p.name))
        self.connect(self.pluginSignalMapper,
                     SIGNAL("mapped(const QString &)"),
                     self.image_browser.handlePluginClicked)


    def createDocks(self):
        """Create all dock widgets and add them to DockArea."""
        self.image_view = ImageView(self.settings, self)
        self.image_browser = ImageBrowser(self.settings, self)
        self.fitter = Fitter(self.settings, self)

        self.roi_editor_h = RoiEditor(self.settings,
                                      self.image_view, self, name='ROIH',
                                      pen=(1, 9), axis=1)
        self.roi_editor_v = RoiEditor(self.settings,
                                      self.image_view, self, name='ROIV',
                                      pen=(1, 1), axis=0)
        self.roi_editor_int = RoiEditor(self.settings,
                                        self.image_view, self, name='ROI Int',
                                        pen=(1, 2), axis=1)
        self.roi_editor_err = RoiEditor(self.settings,
                                        self.image_view, self, name='ROI Err',
                                        pen=(1, 3), axis=1)
        self.roi_plot_h = Plot1d(parent=self, title='ROI H')
        self.roi_plot_v = Plot1d(parent=self, title='ROI V')

        self.analyzer = Analyzer(self.settings, parent=self)

        # Create docks for all widgets
        self.dock_image_view = Dock('Image View', widget=self.image_view)
        self.dock_image_browser = Dock('Image Browser',
                                       widget=self.image_browser)
        self.dock_fitter = Dock('Fitter', widget=self.fitter)
        self.dock_roi_h = Dock('ROIH', widget=self.roi_editor_h)
        self.dock_roi_v = Dock('ROIV', widget=self.roi_editor_v)
        self.dock_roi_int = Dock('ROI Int', widget=self.roi_editor_int)
        self.dock_roi_err = Dock('ROI Err', widget=self.roi_editor_err)

        self.dock_roi_plot_h = Dock('ROIH Plot', widget=self.roi_plot_h)
        self.dock_roi_plot_v = Dock('ROIV Plot', widget=self.roi_plot_v)
        self.dock_analyzer = Dock('Analyze', widget=self.analyzer)

        self.dock_area.addDock(self.dock_image_view, position='top')
        self.dock_area.addDock(self.dock_image_browser, position='right',
                               relativeTo=self.dock_image_view)
        self.dock_area.addDock(self.dock_fitter, position='left',
                               relativeTo=self.dock_image_view)
        self.dock_area.addDock(self.dock_roi_h, position='bottom',
                               relativeTo=self.dock_fitter)
        self.dock_area.addDock(self.dock_roi_v, position='below',
                               relativeTo=self.dock_roi_h)
        self.dock_area.addDock(self.dock_roi_int, position='below',
                               relativeTo=self.dock_roi_v)
        self.dock_area.addDock(self.dock_roi_err, position='below',
                               relativeTo=self.dock_roi_int)
        self.dock_area.addDock(self.dock_roi_plot_h, position='below',
                               relativeTo=self.dock_image_view)
        self.dock_area.addDock(self.dock_roi_plot_v, position='right',
                               relativeTo=self.dock_roi_plot_h)
        self.dock_area.addDock(self.dock_analyzer, position='top',
                               relativeTo=self.dock_image_browser)

    def initAfterCreatingDockWidgets(self):
        self.setWindowTitle(self.image_browser.current_directory)

    def connectSignalsToSlots(self):
        self.actionOpen_Directory.triggered.connect(self.image_browser.handleOpenDirectoryAction)
        self.actionDark_File.triggered.connect(self.image_browser.handleDarkFileAction)
        self.actionRefresh.triggered.connect(self.image_browser.handleRefreshAction)
        self.actionSave.triggered.connect(self.image_browser.handleSaveAnalysis)

        self.image_browser.windowTitleChanged.connect(self.setWindowTitle)
        # self.image_browser.imageChanged.connect(self.image_view.handleImageChanged)
        self.image_browser.imageChanged.connect(self.fitter.handleImageChanged)
        self.image_browser.imageChanged.connect(self.analyzer.handleImageChanged)

        self.roi_editor_int.roiChanged.connect(self.image_browser.handleRoiChanged)
        self.roi_editor_err.roiChanged.connect(self.image_browser.handleROIErrChanged)
        self.roi_editor_h.roiChanged.connect(self.image_browser.handleROIHChanged)
        self.roi_editor_v.roiChanged.connect(self.image_browser.handleROIVChanged)

        self.roi_editor_h.roiChanged.connect(self.fitter.handleROIHChanged)
        self.roi_editor_h.roiChanged.connect(self.analyzer.handleROIHChanged)
        self.roi_editor_v.roiChanged.connect(self.fitter.handleROIVChanged)
        self.roi_editor_v.roiChanged.connect(self.analyzer.handleROIVChanged)
        self.roi_editor_int.roiChanged.connect(self.fitter.handleROIIntChanged)
        self.roi_editor_int.roiChanged.connect(self.analyzer.handleROIIntChanged)
        self.roi_editor_err.roiChanged.connect(self.fitter.handleROIErrChanged)
        self.roi_editor_err.roiChanged.connect(self.analyzer.handleROIErrChanged)

        self.image_view.doubleClicked.connect(self.roi_editor_h.centerROI)
        self.image_view.doubleClicked.connect(self.roi_editor_v.centerROI)

        self.fitter.imageChanged.connect(self.image_view.handleImageChanged)
        self.fitter.horDataChanged.connect(self.roi_plot_h.handleDataChanged)
        self.fitter.verDataChanged.connect(self.roi_plot_v.handleDataChanged)
        self.fitter.doneFitting.connect(self.analyzer.handleDoneFitting)

    def loadSettings(self):
        """Load window state from self.settings"""

        self.settings.beginGroup('mainwindow')
        geometry = self.settings.value('geometry').toByteArray()
        state = self.settings.value('windowstate').toByteArray()
        dock_string = str(self.settings.value('dockstate').toString())
        if dock_string is not "":
            dock_state = eval(dock_string)
            self.dock_area.restoreState(dock_state)
        self.settings.endGroup()

        self.restoreGeometry(geometry)
        self.restoreState(state)

    def saveSettings(self):
        """Save window state to self.settings."""
        self.settings.beginGroup('mainwindow')
        self.settings.setValue('geometry', self.saveGeometry())
        self.settings.setValue('windowstate', self.saveState())
        dock_state = self.dock_area.saveState()
        # dock_state returned here is a python dictionary. Coundn't find a good
        # way to save dicts in QSettings, hence just using representation
        # of it.
        self.settings.setValue('dockstate', repr(dock_state))
        self.settings.endGroup()

    def closeEvent(self, event):
        self.saveSettings()
        self.image_browser.saveSettings()
        self.roi_editor_int.saveSettings()
        self.roi_editor_err.saveSettings()
        self.roi_editor_v.saveSettings()
        self.roi_editor_h.saveSettings()
        self.analyzer.saveSettings()
        super(MainWindow, self).closeEvent(event)

    def setWindowTitle(self, newTitle=''):
        """Prepend IP-BEC to all window titles."""
        title = 'IP-BEC: ' + newTitle
        super(MainWindow, self).setWindowTitle(title)
Esempio n. 7
0
class WidgetBase(BaseClassTemplate):
    def __init__(self, parent=None, hideHistograms=False) -> None:
        BaseClassTemplate.__init__(self, parent=parent)

        self.uiBase = BaseWidgetTemplate()
        self.uiBase.setupUi(self)

        #############################################################
        #                   ATTRIBUTES                              #
        #############################################################

        self.gui_timer = QTimer()  # type: QTimer
        self.gui_timer.timeout.connect(self.updateDisplay)
        if self.uiBase.wao_Display.isChecked():
            self.gui_timer.start(1000. / self.uiBase.wao_frameRate.value())
        self.loopLock = threading.Lock(
        )  # type: Threading.Lock # Asynchronous loop / display safe-threading
        self.hideHistograms = hideHistograms
        #############################################################
        #               PYQTGRAPH DockArea INIT                     #
        #############################################################

        self.area = DockArea()
        self.uiBase.wao_DisplayDock.setWidget(self.area)
        self.gridSH = []

        #############################################################
        #                 CONNECTED BUTTONS                         #
        #############################################################
        # Default path for config files
        self.defaultParPath = "."
        self.defaultAreaPath = "."
        self.uiBase.wao_loadConfig.clicked.connect(self.loadConfig)
        self.uiBase.wao_loadArea.clicked.connect(self.loadArea)
        self.uiBase.wao_saveArea.clicked.connect(self.saveArea)
        self.uiBase.wao_init.clicked.connect(self.initConfig)
        self.uiBase.wao_configFromFile.clicked.connect(self.addConfigFromFile)

        self.uiBase.wao_Display.stateChanged.connect(self.gui_timer_config)
        self.uiBase.wao_frameRate.setValue(2)

        self.uiBase.wao_loadConfig.setDisabled(False)
        self.uiBase.wao_init.setDisabled(True)

        self.disp_checkboxes = []
        self.docks = {}  # type: Dict[str, pg.dockarea.Dock]
        self.viewboxes = {}  # type: Dict[str, pg.ViewBox]
        self.imgs = {}  # type: Dict[str, pg.ImageItem]
        self.hists = {}  # type: Dict[str, pg.HistogramLUTItem]

        self.PupilLines = None
        self.adjustSize()

    def gui_timer_config(self, state) -> None:
        self.uiBase.wao_frameRate.setDisabled(state)
        if state:
            self.gui_timer.start(1000. / self.uiBase.wao_frameRate.value())
        else:
            self.gui_timer.stop()

    def closeEvent(self, event: Any) -> None:
        self.quitGUI(event)

    def quitGUI(self, event: Any = None) -> None:
        reply = QtWidgets.QMessageBox.question(
            self, 'Message', "Are you sure to quit?",
            QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
            QtWidgets.QMessageBox.No)

        if reply == QtWidgets.QMessageBox.Yes:
            if event:
                event.accept()
            quit()
        else:
            if event:
                event.ignore()

    #############################################################
    #                       METHODS                             #
    #############################################################

    def saveArea(self, widget, filename=None):
        '''
            Callback when a area layout file is double clicked in the file browser
            Place the selected file name in the browsing drop-down menu,
            the call the self.loadConfig callback of the load button.
        '''
        if filename is None:
            filepath = QtWidgets.QFileDialog(
                directory=self.defaultAreaPath).getSaveFileName(
                    self, "Select area layout file", "",
                    "area layout file (*.area);;all files (*)")
            filename = filepath[0]

        try:
            with open(filename, "w+") as f:
                st = self.area.saveState()
                f.write(str(st))
        except FileNotFoundError as err:
            warnings.warn(filename + " not loaded: " + err)

    def showDock(self, name):
        for disp_checkbox in self.disp_checkboxes:
            if disp_checkbox.text() == name:
                disp_checkbox.setChecked(True)
                break
        if name in self.docks.keys():
            self.area.addDock(self.docks[name])

    def restoreMyState(self, state):
        typ, contents, _ = state

        if typ == 'dock':
            self.showDock(contents)
        else:
            for o in contents:
                self.restoreMyState(o)

    def loadArea(self, widget=None, filename=None):
        # close all docks
        for disp_checkbox in self.disp_checkboxes:
            disp_checkbox.setChecked(False)
        for dock in self.docks.values():
            if dock.isVisible():
                dock.close()

        if filename is None:
            filepath = QtWidgets.QFileDialog(
                directory=self.defaultAreaPath).getOpenFileName(
                    self, "Select area layout file", "",
                    "area layout file (*.area);;all files (*)")
            filename = filepath[0]

        try:
            with open(filename, "r") as f:
                st = eval(f.readline())

                # restore docks from main area
                if st['main'] is not None:
                    self.restoreMyState(st["main"])

                # restore docks from floating area
                for win in st["float"]:
                    self.restoreMyState(win[0]['main'])

                # rearange dock s as in stored state
                self.area.restoreState(st)
        except FileNotFoundError as err:
            warnings.warn(filename + "not loaded: " + err)

    def addConfigFromFile(self) -> None:
        '''
            Callback when a config file is double clicked in the file browser
            Place the selected file name in the browsing drop-down menu,
            the call the self.loadConfig callback of the load button.
        '''
        filepath = QtWidgets.QFileDialog(
            directory=self.defaultParPath).getOpenFileName(
                self, "Select parameter file", "",
                "parameters file (*.py);;hdf5 file (*.h5);;all files (*)")

        self.uiBase.wao_selectConfig.clear()
        self.uiBase.wao_selectConfig.addItem(str(filepath[0]))

        self.loadConfig(configFile=self.uiBase.wao_selectConfig.currentText())

    def update_displayDock(self):
        guilty_guy = self.sender().text()
        state = self.sender().isChecked()
        if state:
            self.area.addDock(self.docks[guilty_guy])
        elif self.docks[guilty_guy].isVisible():
            self.docks[guilty_guy].close()

    def add_dispDock(self, name: str, parent, type: str = "pg_image") -> Dock:
        checkBox = QtGui.QCheckBox(name, parent)
        checkBox.clicked.connect(self.update_displayDock)
        checkableAction = QtGui.QWidgetAction(parent)
        checkableAction.setDefaultWidget(checkBox)
        parent.addAction(checkableAction)
        self.disp_checkboxes.append(checkBox)

        d = Dock(name)  # , closable=True)
        self.docks[name] = d
        if type == "pg_image":
            img = pg.ImageItem(border='w')
            self.imgs[name] = img

            viewbox = pg.ViewBox()

            viewbox.setAspectLocked(True)
            viewbox.addItem(img)  # Put image in plot area
            self.viewboxes[name] = viewbox
            iv = pg.ImageView(view=viewbox, imageItem=img)
            viewbox.invertY(False)

            if (self.hideHistograms):
                iv.ui.histogram.hide()
            iv.ui.histogram.autoHistogramRange()  # init levels
            iv.ui.histogram.setMaximumWidth(100)
            iv.ui.menuBtn.hide()
            iv.ui.roiBtn.hide()
            d.addWidget(iv)
        elif type == "pg_plot":
            img = pg.PlotItem(border='w')
            self.imgs[name] = img
            d.addWidget(img)
        elif type == "MPL":
            img = MatplotlibWidget()
            self.imgs[name] = img
            d.addWidget(img)
        # elif type == "SR":
        #     d.addWidget(self.uiBase.wao_Strehl)
        return d

    def loadConfig(self, *args, **kwargs) -> None:
        '''
            Callback when 'LOAD' button is hit
        '''
        for groupbox in [
                self.uiBase.wao_phasesgroup_tb, self.uiBase.wao_imagesgroup_tb,
                self.uiBase.wao_graphgroup_tb
        ]:
            layout = groupbox.menu()
            while layout and not layout.isEmpty():
                w = layout.children()[0]
                layout.removeAction(w)
                w.setParent(None)
        self.disp_checkboxes.clear()

        # TODO: remove self.imgs, self.viewboxes and self.docks children
        for _, dock in self.docks.items():
            if dock.isVisible():
                dock.close()

        self.docks.clear()
        self.imgs.clear()
        self.viewboxes.clear()

        self.wao_phasesgroup_cb = QtGui.QMenu(self)
        self.uiBase.wao_phasesgroup_tb.setMenu(self.wao_phasesgroup_cb)
        self.uiBase.wao_phasesgroup_tb.setText('Select')
        self.uiBase.wao_phasesgroup_tb.setPopupMode(
            QtWidgets.QToolButton.InstantPopup)

        self.wao_graphgroup_cb = QtGui.QMenu(self)
        self.uiBase.wao_graphgroup_tb.setMenu(self.wao_graphgroup_cb)
        self.uiBase.wao_graphgroup_tb.setText('Select')
        self.uiBase.wao_graphgroup_tb.setPopupMode(
            QtWidgets.QToolButton.InstantPopup)

        self.uiBase.wao_imagesgroup_tb.setText('Select')
        self.wao_imagesgroup_cb = QtGui.QMenu(self)
        self.uiBase.wao_imagesgroup_tb.setMenu(self.wao_imagesgroup_cb)
        self.uiBase.wao_imagesgroup_tb.setPopupMode(
            QtWidgets.QToolButton.InstantPopup)

        # self.uiBase.wao_init.setDisabled(False)
        #
        # if (hasattr(self.sim.config, "layout")):
        #     area_filename = self.defaultAreaPath + "/" + self.sim.config.layout + ".area"
        #     self.loadArea(filename=area_filename)
        #
        # self.adjustSize()

    def loadDefaultConfig(self) -> None:
        import glob
        parlist = sorted(glob.glob(self.defaultParPath + "/*.py"))
        self.uiBase.wao_selectConfig.clear()
        self.uiBase.wao_selectConfig.addItems(
            [parlist[i].split('/')[-1] for i in range(len(parlist))])

    def initConfig(self) -> None:
        self.loopLock.acquire(True)
        self.uiBase.wao_loadConfig.setDisabled(True)
        self.uiBase.wao_init.setDisabled(True)
        self.thread = WorkerThread(self.initConfigThread)
        self.thread.finished.connect(self.initConfigFinished)
        self.thread.start()

    def initConfigThread(self) -> None:
        pass

    def initConfigFinished(self) -> None:
        self.uiBase.wao_loadConfig.setDisabled(False)
        self.uiBase.wao_init.setDisabled(False)
        self.loopLock.release()

    def updateDisplay(self) -> None:
        if not self.loopLock.acquire(False):
            return
        else:
            try:
                pass
            finally:
                self.loopLock.release()

    def addSHGrid(self, pg_image, valid_sub, sspsize, pitch):
        # First remove the old grid, if any
        if self.PupilLines is not None:
            pg_image.removeItem(self.PupilLines)

        nssp_tot = valid_sub[0].size
        connect = np.ones((nssp_tot, 5), dtype=bool)
        connect[:, -1] = 0  # don't draw the segment between each trace
        roi_x = np.ones((nssp_tot, 5), dtype=int)
        roi_y = np.ones((nssp_tot, 5), dtype=int)
        for idx_ssp in range(nssp_tot):
            (x, y) = (valid_sub[0][idx_ssp], valid_sub[1][idx_ssp])
            roi_x[idx_ssp, :] = [x, x, x + sspsize, x + sspsize, x]
            roi_y[idx_ssp, :] = [y, y + sspsize, y + sspsize, y, y]
        self.PupilLines = PupilBoxes(roi_x, roi_y)
        pg_image.addItem(self.PupilLines)

    def printInPlace(self, text: str) -> None:
        # This seems to trigger the GUI and keep it responsive
        print(text, end='\r', flush=True)

    def run(self):
        self.loopOnce()
        if not self.stop:
            QTimer.singleShot(0, self.run)  # Update loop
Esempio n. 8
0
class AWGUi(AWGForm, AWGBase):
    varDictChanged = QtCore.pyqtSignal(object)

    def __init__(self, deviceClass, config, globalDict, parent=None):
        AWGBase.__init__(self, parent)
        AWGForm.__init__(self)
        self.config = config
        self.configname = 'AWGUi.' + deviceClass.displayName
        self.globalDict = globalDict
        self.autoSave = self.config.get(self.configname + '.autoSave', True)
        self.waveformCache = OrderedDict()
        self.settingsDict = self.config.get(self.configname + '.settingsDict',
                                            dict())
        self.settingsName = self.config.get(self.configname + '.settingsName',
                                            '')
        # self.settingsDict=dict()
        # self.settingsName=''
        self.recentFiles = self.config.get(
            self.configname + '.recentFiles', dict()
        )  #dict of form {basename: filename}, where filename has path and basename doesn't
        self.lastDir = self.config.get(self.configname + '.lastDir',
                                       getProject().configDir)
        Settings.deviceProperties = deviceClass.deviceProperties
        Settings.saveIfNecessary = self.saveIfNecessary
        Settings.replot = self.replot
        for settings in list(
                self.settingsDict.values()
        ):  #make sure all pickled settings are consistent with device, in case it changed
            for channel in range(deviceClass.deviceProperties['numChannels']):
                if channel >= len(settings.channelSettingsList
                                  ):  #create new channels if it's necessary
                    settings.channelSettingsList.append({
                        'segmentDataRoot':
                        AWGSegmentNode(None),
                        'segmentTreeState':
                        None,
                        'plotEnabled':
                        True,
                        'plotStyle':
                        Settings.plotStyles.lines
                    })
                else:
                    settings.channelSettingsList[channel].setdefault(
                        'segmentDataRoot', AWGSegmentNode(None))
                    settings.channelSettingsList[channel].setdefault(
                        'segmentTreeState', None)
                    settings.channelSettingsList[channel].setdefault(
                        'plotEnabled', True)
                    settings.channelSettingsList[channel].setdefault(
                        'plotStyle', Settings.plotStyles.lines)
        self.settings = Settings(
        )  #we always run settings through the constructor
        if self.settingsName in self.settingsDict:
            self.settings.update(self.settingsDict[self.settingsName])
        self.device = deviceClass(self.settings)

    def setupUi(self, parent):
        logger = logging.getLogger(__name__)
        AWGForm.setupUi(self, parent)
        self.setWindowTitle(self.device.displayName)

        self._varAsOutputChannelDict = dict()
        self.area = DockArea()
        self.splitter.insertWidget(0, self.area)
        self.awgChannelUiList = []
        for channel in range(self.device.deviceProperties['numChannels']):
            awgChannelUi = AWGChannelUi(channel,
                                        self.settings,
                                        self.globalDict,
                                        self.waveformCache,
                                        parent=self)
            awgChannelUi.setupUi(awgChannelUi)
            awgChannelUi.dependenciesChanged.connect(
                self.onDependenciesChanged)
            self.awgChannelUiList.append(awgChannelUi)
            dock = Dock("AWG Channel {0}".format(channel))
            dock.addWidget(awgChannelUi)
            self.area.addDock(dock, 'right')
            self.device.waveforms[channel] = awgChannelUi.waveform
        self.refreshVarDict()

        # Settings control
        self.saveButton.clicked.connect(self.onSave)
        self.removeButton.clicked.connect(self.onRemove)
        self.reloadButton.clicked.connect(self.onReload)
        self.settingsModel = QtCore.QStringListModel()
        self.settingsComboBox.setModel(self.settingsModel)
        self.settingsModel.setStringList(sorted(self.settingsDict.keys()))
        self.settingsComboBox.setCurrentIndex(
            self.settingsComboBox.findText(self.settingsName))
        self.settingsComboBox.currentIndexChanged[str].connect(self.onLoad)
        self.settingsComboBox.lineEdit().editingFinished.connect(
            self.onComboBoxEditingFinished)
        self.autoSaveCheckBox.setChecked(self.autoSave)
        self.saveButton.setEnabled(not self.autoSave)
        self.saveButton.setVisible(not self.autoSave)
        self.reloadButton.setEnabled(not self.autoSave)
        self.reloadButton.setVisible(not self.autoSave)
        self.autoSaveCheckBox.stateChanged.connect(self.onAutoSave)

        #programming options table
        self.programmingOptionsTable.setupUi(
            globalDict=self.globalDict, parameterDict=self.device.parameters())
        self.programmingOptionsTable.valueChanged.connect(self.device.update)

        # Table
        self.tableModel = AWGTableModel(self.settings, self.globalDict)
        self.tableView.setModel(self.tableModel)
        self.tableModel.valueChanged.connect(self.onValue)
        self.delegate = MagnitudeSpinBoxDelegate(self.globalDict)
        self.tableView.setItemDelegateForColumn(self.tableModel.column.value,
                                                self.delegate)

        #File
        self.filenameModel = QtCore.QStringListModel()
        self.filenameComboBox.setModel(self.filenameModel)
        self.filenameModel.setStringList([
            basename for basename, filename in list(self.recentFiles.items())
            if os.path.exists(filename)
        ])
        self.filenameComboBox.setCurrentIndex(
            self.filenameComboBox.findText(
                os.path.basename(self.settings.filename)))
        self.filenameComboBox.currentIndexChanged[str].connect(self.onFilename)
        self.removeFileButton.clicked.connect(self.onRemoveFile)
        self.newFileButton.clicked.connect(self.onNewFile)
        self.openFileButton.clicked.connect(self.onOpenFile)
        self.saveFileButton.clicked.connect(self.onSaveFile)
        self.reloadFileButton.clicked.connect(self.onReloadFile)

        #cache
        self.cacheDepthSpinBox.setValue(self.settings.cacheDepth)
        self.cacheDepthSpinBox.valueChanged.connect(self.onCacheDepth)
        self.clearCacheButton.clicked.connect(self.onClearCache)

        #status bar
        self.label = QtGui.QLabel('Sample Rate: {0}'.format(
            self.settings.deviceProperties['sampleRate']))
        self.statusbar.addWidget(self.label)

        #Restore GUI state
        state = self.config.get(self.configname + '.state')
        pos = self.config.get(self.configname + '.pos')
        size = self.config.get(self.configname + '.size')
        isMaximized = self.config.get(self.configname + '.isMaximized')
        dockAreaState = self.config.get(self.configname + '.dockAreaState')
        guiState = self.config.get(self.configname + ".guiState")
        restoreGuiState(self, guiState)
        try:
            if pos:
                self.move(pos)
            if size:
                self.resize(size)
            if isMaximized:
                self.showMaximized()
            if state:
                self.restoreState(state)
            for awgChannelUi in self.awgChannelUiList:
                channelGuiState = self.config[
                    self.configname +
                    "channel{0}.guiState".format(awgChannelUi.channel)]
                restoreGuiState(awgChannelUi, channelGuiState)
        except Exception as e:
            logger.warning(
                "Error on restoring state in AWGUi {0}. Exception occurred: {1}"
                .format(self.device.displayName, e))
        try:
            if dockAreaState:
                self.area.restoreState(dockAreaState)
        except Exception as e:
            logger.warning(
                "Cannot restore dock state in AWGUi {0}. Exception occurred: {1}"
                .format(self.device.displayName, e))
            self.area.deleteLater()
            self.area = DockArea()
            self.splitter.insertWidget(0, self.area)
            for channelUi in self.awgChannelUiList:
                dock = Dock("AWG Channel {0}".format(channel))
                dock.addWidget(channelUi)
                self.area.addDock(dock, 'right')
        self.saveIfNecessary()

    def onCacheDepth(self, newVal):
        self.settings.cacheDepth = newVal
        self.saveIfNecessary()

    def onClearCache(self):
        self.waveformCache.clear()

    def onComboBoxEditingFinished(self):
        """a settings name is typed into the combo box"""
        currentText = str(self.settingsComboBox.currentText())
        if self.settingsName != currentText:
            self.settingsName = currentText
            if self.settingsName not in self.settingsDict:
                self.settingsDict[self.settingsName] = copy.deepcopy(
                    self.settings)
            self.onLoad(self.settingsName)

    def saveIfNecessary(self):
        """save the current settings if autosave is on and something has changed"""
        currentText = str(self.settingsComboBox.currentText())
        if self.settingsDict.get(
                self.settingsName
        ) != self.settings or currentText != self.settingsName:
            if self.autoSave:
                self.onSave()
            else:
                self.saveButton.setEnabled(True)

    def replot(self):
        """plot all channels"""
        for channelUi in self.awgChannelUiList:
            channelUi.replot()

    def onSave(self):
        """save current settings"""
        self.settingsName = str(self.settingsComboBox.currentText())
        self.settingsDict[self.settingsName] = copy.deepcopy(self.settings)
        with BlockSignals(self.settingsComboBox) as w:
            self.settingsModel.setStringList(sorted(self.settingsDict.keys()))
            w.setCurrentIndex(w.findText(self.settingsName))
        self.saveButton.setEnabled(False)

    def saveConfig(self):
        """save GUI configuration to config"""
        self.config[self.configname + ".guiState"] = saveGuiState(self)
        for awgChannelUi in self.awgChannelUiList:
            self.config[self.configname + "channel{0}.guiState".format(
                awgChannelUi.channel)] = saveGuiState(awgChannelUi)
            self.settings.channelSettingsList[awgChannelUi.channel][
                'segmentTreeState'] = awgChannelUi.segmentView.saveTreeState()
        self.config[self.configname + '.state'] = self.saveState()
        self.config[self.configname + '.pos'] = self.pos()
        self.config[self.configname + '.size'] = self.size()
        self.config[self.configname + '.isMaximized'] = self.isMaximized()
        self.config[self.configname + '.isVisible'] = self.isVisible()
        self.config[self.configname + '.dockAreaState'] = self.area.saveState()
        self.config[self.configname + '.settingsDict'] = self.settingsDict
        self.config[self.configname + '.settingsName'] = self.settingsName
        self.config[self.configname + '.autoSave'] = self.autoSave
        self.config[self.configname + '.recentFiles'] = self.recentFiles
        self.config[self.configname + '.lastDir'] = self.lastDir

    def onRemove(self):
        """Remove current settings from combo box"""
        name = str(self.settingsComboBox.currentText())
        if name in self.settingsDict:
            self.settingsDict.pop(name)
            self.settingsName = list(
                self.settingsDict.keys())[0] if self.settingsDict else ''
            with BlockSignals(self.settingsComboBox) as w:
                self.settingsModel.setStringList(
                    sorted(self.settingsDict.keys()))
                w.setCurrentIndex(w.findText(self.settingsName))
            self.onLoad(self.settingsName)

    def onReload(self):
        """Reload settings"""
        name = str(self.settingsComboBox.currentText())
        self.onLoad(name)

    def onLoad(self, name):
        """load settings"""
        for channelUi in self.awgChannelUiList:
            self.settings.channelSettingsList[channelUi.channel][
                'segmentTreeState'] = channelUi.segmentView.saveTreeState()
        name = str(name)
        if name in self.settingsDict:
            self.settingsName = name
            self.tableModel.beginResetModel()
            [
                channelUi.segmentModel.beginResetModel()
                for channelUi in self.awgChannelUiList
            ]
            self.settings.update(self.settingsDict[self.settingsName])
            self.programmingOptionsTable.setParameters(
                self.device.parameters())
            self.saveButton.setEnabled(False)
            with BlockSignals(self.filenameComboBox) as w:
                w.setCurrentIndex(
                    w.findText(os.path.basename(self.settings.filename)))
            with BlockSignals(self.cacheDepthSpinBox) as w:
                w.setValue(self.settings.cacheDepth)
            for channelUi in self.awgChannelUiList:
                channelUi.waveform.updateDependencies()
                channelUi.plotCheckbox.setChecked(
                    self.settings.channelSettingsList[
                        channelUi.channel]['plotEnabled'])
                with BlockSignals(channelUi.styleComboBox) as w:
                    w.setCurrentIndex(self.settings.channelSettingsList[
                        channelUi.channel]['plotStyle'])
                channelUi.segmentModel.root = self.settings.channelSettingsList[
                    channelUi.channel]['segmentDataRoot']
                channelUi.replot()
            self.onDependenciesChanged()
            self.saveButton.setEnabled(False)
            self.tableModel.endResetModel()
            [
                channelUi.segmentModel.endResetModel()
                for channelUi in self.awgChannelUiList
            ]
            for channelUi in self.awgChannelUiList:
                channelUi.segmentView.restoreTreeState(
                    self.settings.channelSettingsList[
                        channelUi.channel]['segmentTreeState'])

    def onAutoSave(self, checked):
        """autosave is changed"""
        self.autoSave = checked
        self.saveButton.setEnabled(not checked)
        self.saveButton.setVisible(not checked)
        self.reloadButton.setEnabled(not checked)
        self.reloadButton.setVisible(not checked)
        if checked:
            self.onSave()

    def onValue(self, var=None, value=None):
        """variable value is changed in the table"""
        self.saveIfNecessary()
        self.replot()

    def evaluate(self, name):
        """re-evaluate the text in the tableModel (happens when a global changes)"""
        self.tableModel.evaluate(name)
        self.programmingOptionsTable.evaluate(name)

    def refreshVarDict(self):
        """refresh the variable dictionary by checking all waveform dependencies"""
        allDependencies = set()
        [
            channelUi.waveform.updateDependencies()
            for channelUi in self.awgChannelUiList
        ]
        [
            allDependencies.update(channelUi.waveform.dependencies)
            for channelUi in self.awgChannelUiList
        ]
        default = lambda varname: {
            'value': Q(1, 'us'),
            'text': None
        } if varname.startswith('Duration') else {
            'value': Q(0),
            'text': None
        }
        deletions = [
            varname for varname in self.settings.varDict
            if varname not in allDependencies
        ]
        [self.settings.varDict.pop(varname) for varname in deletions
         ]  #remove all values that aren't dependencies anymore
        [
            self.settings.varDict.setdefault(varname, default(varname))
            for varname in allDependencies
        ]  #add missing values
        self.settings.varDict.sort(key=lambda val: -1 if val[0].startswith(
            'Duration') else ord(str(val[0])[0]))
        self.varDictChanged.emit(self.varAsOutputChannelDict)
        for channelUi in self.awgChannelUiList:
            channelUi.replot()

    def onDependenciesChanged(self, channel=None):
        """When dependencies change, refresh all variables"""
        self.tableModel.beginResetModel()
        self.refreshVarDict()
        self.tableModel.endResetModel()
        self.saveIfNecessary()

    def onFilename(self, basename):
        """filename combo box is changed. Open selected file"""
        basename = str(basename)
        filename = self.recentFiles[basename]
        if os.path.isfile(filename) and filename != self.settings.filename:
            self.openFile(filename)

    def onRemoveFile(self):
        """Remove file button is clicked. Remove filename from combo box."""
        text = str(self.filenameComboBox.currentText())
        index = self.filenameComboBox.findText(text)
        if text in self.recentFiles:
            self.recentFiles.pop(text)
        with BlockSignals(self.filenameComboBox) as w:
            self.filenameModel.setStringList(list(self.recentFiles.keys()))
            w.setCurrentIndex(-1)
            self.onFilename(w.currentText())

    def onNewFile(self):
        """New button is clicked. Pop up dialog asking for new name, and create file."""
        filename, _ = QtWidgets.QFileDialog.getSaveFileName(
            self, 'New File', self.lastDir, 'YAML (*.yml)')
        if filename:
            self.lastDir, basename = os.path.split(filename)
            self.recentFiles[basename] = filename
            self.settings.filename = filename
            with BlockSignals(self.filenameComboBox) as w:
                self.filenameModel.setStringList(list(self.recentFiles.keys()))
                w.setCurrentIndex(w.findText(basename))
            self.onSaveFile()

    def onOpenFile(self):
        """Open file button is clicked. Pop up dialog asking for filename."""
        filename, _ = QtWidgets.QFileDialog.getOpenFileName(
            self, 'Select File', self.lastDir, 'YAML (*.yml)')
        if filename:
            self.openFile(filename)

    def openFile(self, filename):
        """Open the file 'filename'"""
        if os.path.exists(filename):
            self.lastDir, basename = os.path.split(filename)
            self.recentFiles[basename] = filename
            self.settings.filename = filename
            with BlockSignals(self.filenameComboBox) as w:
                self.filenameModel.setStringList(list(self.recentFiles.keys()))
                w.setCurrentIndex(w.findText(basename))
            with open(filename, 'r') as f:
                yamldata = yaml.load(f)
            variables = yamldata.get('variables')
            channelData = yamldata.get('channelData')
            self.tableModel.beginResetModel()
            [
                channelUi.segmentModel.beginResetModel()
                for channelUi in self.awgChannelUiList
            ]
            if channelData:
                for channelUi in self.awgChannelUiList:
                    if channelUi.channel < len(channelData):
                        self.settings.channelSettingsList[channelUi.channel][
                            'segmentDataRoot'] = self.convertListToNodes(
                                channelData[channelUi.channel], isRoot=True)
                        channelUi.segmentModel.root = self.settings.channelSettingsList[
                            channelUi.channel]['segmentDataRoot']
            if variables:
                for varname, vardata in list(variables.items()):
                    self.settings.varDict.setdefault(varname, dict())
                    self.settings.varDict[varname]['value'] = Q(
                        vardata['value'], vardata['unit'])
                    self.settings.varDict[varname]['text'] = vardata['text']
            for channelUi in self.awgChannelUiList:
                channelUi.waveform.updateDependencies()
                channelUi.replot()
            self.onDependenciesChanged()
            self.tableModel.endResetModel()
            [
                channelUi.segmentModel.endResetModel()
                for channelUi in self.awgChannelUiList
            ]
            [
                channelUi.segmentView.expandAll()
                for channelUi in self.awgChannelUiList
            ]
        else:
            logging.getLogger(__name__).warning(
                "file '{0}' does not exist".format(filename))
            if filename in self.recentFiles:
                del self.recentFiles[filename]
                with BlockSignals(self.filenameComboBox) as w:
                    self.filenameModel.setStringList(
                        list(self.recentFiles.keys()))
                    w.setCurrentIndex(-1)

    def convertNodeToList(self, node):
        nodeList = []
        for childNode in node.children:
            if childNode.nodeType == nodeTypes.segment:
                nodeList.append({
                    'equation': childNode.equation,
                    'duration': childNode.duration,
                    'enabled': childNode.enabled
                })
            elif childNode.nodeType == nodeTypes.segmentSet:
                nodeList.append({
                    'repetitions': childNode.repetitions,
                    'enabled': childNode.enabled,
                    'segments': self.convertNodeToList(childNode)
                })
        return nodeList

    def convertListToNodes(self,
                           data,
                           parent=None,
                           enabled=True,
                           repetitions=None,
                           isRoot=False):
        node = AWGSegmentNode(parent=None) if isRoot else AWGSegmentSet(
            parent=parent, enabled=enabled, repetitions=repetitions)
        for segment in data:
            if 'duration' in segment:
                childNode = AWGSegment(parent=node,
                                       equation=segment['equation'],
                                       duration=segment['duration'],
                                       enabled=segment['enabled'])
                node.children.append(childNode)
            elif 'repetitions' in segment:
                segmentSet = self.convertListToNodes(
                    segment['segments'],
                    parent=node,
                    enabled=segment['enabled'],
                    repetitions=segment['repetitions'])
                node.children.append(segmentSet)
            else:
                logging.getLogger(__name__).error(
                    "Unable to convert list to nodes")
        return node

    def onSaveFile(self):
        """Save button is clicked. Save data to segment file"""
        channelData = []
        for channelSettings in self.settings.channelSettingsList:
            segmentData = self.convertNodeToList(
                channelSettings['segmentDataRoot'])
            channelData.append(segmentData)
        yamldata = {'channelData': channelData}
        variables = {
            varname: {
                'value': float(varValueTextDict['value'].toStringTuple()[0]),
                'unit': varValueTextDict['value'].toStringTuple()[1],
                'text': varValueTextDict['text']
            }
            for varname, varValueTextDict in list(
                self.settings.varDict.items())
        }
        yamldata.update({'variables': variables})
        with open(self.settings.filename, 'w') as f:
            yaml.dump(yamldata, f, default_flow_style=False)

    def onReloadFile(self):
        self.openFile(self.settings.filename)

    @QtCore.pyqtProperty(dict)
    def varAsOutputChannelDict(self):
        """dict of output channels, for use in scans"""
        for varname in self.settings.varDict:
            if varname not in self._varAsOutputChannelDict:
                self._varAsOutputChannelDict[varname] = VarAsOutputChannel(
                    self, varname, self.globalDict)
        deletions = [
            varname for varname in self._varAsOutputChannelDict
            if varname not in self.settings.varDict
        ]
        [self._varAsOutputChannelDict.pop(varname) for varname in deletions
         ]  #remove all values that aren't dependencies anymore
        return self._varAsOutputChannelDict

    def close(self):
        self.saveConfig()
        numTempAreas = len(self.area.tempAreas)
        for i in range(numTempAreas):
            if len(self.area.tempAreas) > 0:
                self.area.tempAreas[0].win.close()
        super(AWGUi, self).close()
Esempio n. 9
0
class AWGOptimizer(Form, Base):
    def __init__(self, deviceClass, config, parent=None):
        Base.__init__(self, parent)
        Form.__init__(self)
        Form.setupUi(self, self)
        self.config = config
        self.configname = "AWGOptimizer"
        self.setWindowTitle("AWG Optimizer")
        guiState = self.config.get(self.configname+".guiState")
        state = self.config.get(self.configname+'.state')
        pos = self.config.get(self.configname+'.pos')
        size = self.config.get(self.configname+'.size')
        isMaximized = self.config.get(self.configname+'.isMaximized')
        restoreGuiState(self, self.config.get(self.configname+".guiState"))
        if state: self.restoreState(state)
        if pos: self.move(pos)
        if size: self.resize(size)
        if isMaximized: self.showMaximized()

        self.show()
        self.awgUi = AWGUi(deviceClass, config, dict())
        self.awgUi.setupUi(self.awgUi)
        self.splitter.insertWidget(1, self.awgUi)

        #oscilloscope plot window
        name = "Oscilloscope Trace"
        self.scopeDock = Dock(name)
        self.scopePlot = CoordinatePlotWidget(self, name=name)
        self.scopeView = self.scopePlot._graphicsView
        self.scopeDock.addWidget(self.scopePlot)
        self.area = DockArea()
        self.area.addDock(self.scopeDock)
        self.plotDict ={name: {"dock":self.scopeDock, "widget":self.scopePlot, "view":self.scopeView}}
        self.verticalLayout.insertWidget(0, self.area)

        #trace ui
        self.penicons = pens.penicons().penicons()
        self.traceui = Traceui.Traceui(self.penicons, self.config, self.configname, self.plotDict, hasMeasurementLog=False, highlightUnsaved=False)
        self.traceui.setupUi(self.traceui)
        traceDock = Dock("Traces")
        traceDock.addWidget(self.traceui)
        self.area.addDock(traceDock, 'left')
        self.device = self.awgUi.device

        self.measureWaveformButton.clicked.connect(self.onMeasureWaveform)
        self.optimizeButton.clicked.connect(self.onOptimize)

        dockAreaState = self.config.get(self.configname+'.dockAreaState')
        try:
            if dockAreaState: self.area.restoreState(dockAreaState)
        except Exception as e:
            print(e)

    def saveConfig(self):
        self.config[self.configname+".guiState"] = saveGuiState(self)
        self.config[self.configname+'.state'] = self.saveState()
        self.config[self.configname+'.pos'] = self.pos()
        self.config[self.configname+'.size'] = self.size()
        self.config[self.configname+'.isMaximized'] = self.isMaximized()
        self.config[self.configname+'.dockAreaState'] = self.area.saveState()
        self.awgUi.saveConfig()

    def closeEvent(self, e):
        self.saveConfig()

    def onMeasureWaveform(self):
        pass

    def onOptimize(self):
        pass
Esempio n. 10
0
class DockAreaTabWidgetBase(QtGui.QWidget):
    def __init__(self, *args, **kwargs):
        self.main = kwargs.pop("main")
        tabName = kwargs.pop("tabName")
        QtGui.QWidget.__init__(self, *args, **kwargs)
        self.setObjectName(tabName)
        self._layout = QtGui.QGridLayout(self)

    def _InitDocks(self):

        # Define docking area
        if hasattr(self, "_dockArea"):
            self._dockArea.setParent(None)
        self._dockArea = DockArea()

        self._plotDocks = self._defaultDockPos.keys()

        # Add dock to area
        for dock, pos in self._defaultDockPos.iteritems():
            self._dockArea.addDock(dock, *pos)

        self._layout.addWidget(self._dockArea, 0, 0, 1, 1)

    def Shown(self):
        self.DrawFrame()

    def DrawFrame(self, clear=True):
        if clear:
            self.ClearPlots()

        for dock in self._plotDocks:
            if not dock.automaticDraw:
                continue
            dock.DrawPlot()

    def ClearPlots(self):
        for dock in self._plotDocks:
            if not dock.automaticDraw:
                continue
            dock.ClearPlot()

    def AutoscalePlots(self):
        for dock in self._plotDocks:
            if not dock.automaticDraw:
                continue
            dock.Autoscale()

    def SaveState(self):
        res = {}
        res["dockingState"] = self._dockArea.saveState()
        for dock in self._plotDocks:
            res["dock_" + dock.name()] = dock.SaveState()
        return res

    def SetState(self, state):
        try:
            if "dockingState" in state:
                self._dockArea.restoreState(state["dockingState"])
        except:
            print "Docking area restore failed, restoring defaults:"
            traceback.print_exc()
            print "Restore defaults"
            self._InitDocks()

        for dock in self._plotDocks:
            stateName = "dock_" + dock.name()
            if stateName in state:
                dock.SetState(state[stateName])
Esempio n. 11
0
class AWGUi(AWGForm, AWGBase):
    varDictChanged = QtCore.pyqtSignal(object)
    def __init__(self, deviceClass, config, globalDict, parent=None):
        AWGBase.__init__(self, parent)
        AWGForm.__init__(self)
        self.config = config
        self.configname = 'AWGUi.' + deviceClass.displayName
        self.globalDict = globalDict
        self.autoSave = self.config.get(self.configname+'.autoSave', True)
        self.waveformCache = OrderedDict()
        self.settingsDict = self.config.get(self.configname+'.settingsDict', dict())
        self.settingsName = self.config.get(self.configname+'.settingsName', '')
        # self.settingsDict=dict()
        # self.settingsName=''
        self.recentFiles = self.config.get(self.configname+'.recentFiles', dict()) #dict of form {basename: filename}, where filename has path and basename doesn't
        self.lastDir = self.config.get(self.configname+'.lastDir', getProject().configDir)
        Settings.deviceProperties = deviceClass.deviceProperties
        Settings.saveIfNecessary = self.saveIfNecessary
        Settings.replot = self.replot
        for settings in list(self.settingsDict.values()): #make sure all pickled settings are consistent with device, in case it changed
            for channel in range(deviceClass.deviceProperties['numChannels']):
                if channel >= len(settings.channelSettingsList): #create new channels if it's necessary
                    settings.channelSettingsList.append({
                        'segmentDataRoot':AWGSegmentNode(None),
                        'segmentTreeState':None,
                        'plotEnabled':True,
                        'plotStyle':Settings.plotStyles.lines})
                else:
                    settings.channelSettingsList[channel].setdefault('segmentDataRoot', AWGSegmentNode(None))
                    settings.channelSettingsList[channel].setdefault('segmentTreeState', None)
                    settings.channelSettingsList[channel].setdefault('plotEnabled', True)
                    settings.channelSettingsList[channel].setdefault('plotStyle', Settings.plotStyles.lines)
        self.settings = Settings() #we always run settings through the constructor
        if self.settingsName in self.settingsDict:
            self.settings.update(self.settingsDict[self.settingsName])
        self.device = deviceClass(self.settings)

    def setupUi(self, parent):
        logger = logging.getLogger(__name__)
        AWGForm.setupUi(self, parent)
        self.setWindowTitle(self.device.displayName)

        self._varAsOutputChannelDict = dict()
        self.area = DockArea()
        self.splitter.insertWidget(0, self.area)
        self.awgChannelUiList = []
        for channel in range(self.device.deviceProperties['numChannels']):
            awgChannelUi = AWGChannelUi(channel, self.settings, self.globalDict, self.waveformCache, parent=self)
            awgChannelUi.setupUi(awgChannelUi)
            awgChannelUi.dependenciesChanged.connect(self.onDependenciesChanged)
            self.awgChannelUiList.append(awgChannelUi)
            dock = Dock("AWG Channel {0}".format(channel))
            dock.addWidget(awgChannelUi)
            self.area.addDock(dock, 'right')
            self.device.waveforms[channel] = awgChannelUi.waveform
        self.refreshVarDict()

        # Settings control
        self.saveButton.clicked.connect( self.onSave )
        self.removeButton.clicked.connect( self.onRemove )
        self.reloadButton.clicked.connect( self.onReload )
        self.settingsModel = QtCore.QStringListModel()
        self.settingsComboBox.setModel(self.settingsModel)
        self.settingsModel.setStringList( sorted(self.settingsDict.keys()) )
        self.settingsComboBox.setCurrentIndex( self.settingsComboBox.findText(self.settingsName) )
        self.settingsComboBox.currentIndexChanged[str].connect( self.onLoad )
        self.settingsComboBox.lineEdit().editingFinished.connect( self.onComboBoxEditingFinished )
        self.autoSaveCheckBox.setChecked(self.autoSave)
        self.saveButton.setEnabled( not self.autoSave )
        self.saveButton.setVisible( not self.autoSave )
        self.reloadButton.setEnabled( not self.autoSave )
        self.reloadButton.setVisible( not self.autoSave )
        self.autoSaveCheckBox.stateChanged.connect(self.onAutoSave)

        #programming options table
        self.programmingOptionsTable.setupUi(globalDict=self.globalDict, parameterDict=self.device.parameters())
        self.programmingOptionsTable.valueChanged.connect( self.device.update )

        # Table
        self.tableModel = AWGTableModel(self.settings, self.globalDict)
        self.tableView.setModel(self.tableModel)
        self.tableModel.valueChanged.connect(self.onValue)
        self.delegate = MagnitudeSpinBoxDelegate(self.globalDict)
        self.tableView.setItemDelegateForColumn(self.tableModel.column.value, self.delegate)

        #File
        self.filenameModel = QtCore.QStringListModel()
        self.filenameComboBox.setModel(self.filenameModel)
        self.filenameModel.setStringList( [basename for basename, filename in list(self.recentFiles.items()) if os.path.exists(filename)] )
        self.filenameComboBox.setCurrentIndex(self.filenameComboBox.findText(os.path.basename(self.settings.filename)))
        self.filenameComboBox.currentIndexChanged[str].connect(self.onFilename)
        self.removeFileButton.clicked.connect(self.onRemoveFile)
        self.newFileButton.clicked.connect(self.onNewFile)
        self.openFileButton.clicked.connect(self.onOpenFile)
        self.saveFileButton.clicked.connect(self.onSaveFile)
        self.reloadFileButton.clicked.connect(self.onReloadFile)

        #cache
        self.cacheDepthSpinBox.setValue(self.settings.cacheDepth)
        self.cacheDepthSpinBox.valueChanged.connect(self.onCacheDepth)
        self.clearCacheButton.clicked.connect(self.onClearCache)

        #status bar
        self.label = QtGui.QLabel('Sample Rate: {0}'.format(self.settings.deviceProperties['sampleRate']))
        self.statusbar.addWidget(self.label)

        #Restore GUI state
        state = self.config.get(self.configname+'.state')
        pos = self.config.get(self.configname+'.pos')
        size = self.config.get(self.configname+'.size')
        isMaximized = self.config.get(self.configname+'.isMaximized')
        dockAreaState = self.config.get(self.configname+'.dockAreaState')
        guiState = self.config.get(self.configname+".guiState")
        restoreGuiState(self, guiState)
        try:
            if pos:
                self.move(pos)
            if size:
                self.resize(size)
            if isMaximized:
                self.showMaximized()
            if state:
                self.restoreState(state)
            for awgChannelUi in self.awgChannelUiList:
                channelGuiState = self.config[self.configname+"channel{0}.guiState".format(awgChannelUi.channel)]
                restoreGuiState(awgChannelUi, channelGuiState)
        except Exception as e:
            logger.warning("Error on restoring state in AWGUi {0}. Exception occurred: {1}".format(self.device.displayName, e))
        try:
            if dockAreaState:
                self.area.restoreState(dockAreaState)
        except Exception as e:
            logger.warning("Cannot restore dock state in AWGUi {0}. Exception occurred: {1}".format(self.device.displayName, e))
            self.area.deleteLater()
            self.area = DockArea()
            self.splitter.insertWidget(0, self.area)
            for channelUi in self.awgChannelUiList:
                dock = Dock("AWG Channel {0}".format(channel))
                dock.addWidget(channelUi)
                self.area.addDock(dock, 'right')
        self.saveIfNecessary()

    def onCacheDepth(self, newVal):
        self.settings.cacheDepth = newVal
        self.saveIfNecessary()

    def onClearCache(self):
        self.waveformCache.clear()

    def onComboBoxEditingFinished(self):
        """a settings name is typed into the combo box"""
        currentText = str(self.settingsComboBox.currentText())
        if self.settingsName != currentText:
            self.settingsName = currentText
            if self.settingsName not in self.settingsDict:
                self.settingsDict[self.settingsName] = copy.deepcopy(self.settings)
            self.onLoad(self.settingsName)

    def saveIfNecessary(self):
        """save the current settings if autosave is on and something has changed"""
        currentText = str(self.settingsComboBox.currentText())
        if self.settingsDict.get(self.settingsName)!=self.settings or currentText!=self.settingsName:
            if self.autoSave:
                self.onSave()
            else:
                self.saveButton.setEnabled(True)

    def replot(self):
        """plot all channels"""
        for channelUi in self.awgChannelUiList:
            channelUi.replot()

    def onSave(self):
        """save current settings"""
        self.settingsName = str(self.settingsComboBox.currentText())
        self.settingsDict[self.settingsName] = copy.deepcopy(self.settings)
        with BlockSignals(self.settingsComboBox) as w:
            self.settingsModel.setStringList( sorted(self.settingsDict.keys()) )
            w.setCurrentIndex(w.findText(self.settingsName))
        self.saveButton.setEnabled(False)

    def saveConfig(self):
        """save GUI configuration to config"""
        self.config[self.configname+".guiState"] = saveGuiState(self)
        for awgChannelUi in self.awgChannelUiList:
            self.config[self.configname+"channel{0}.guiState".format(awgChannelUi.channel)] = saveGuiState(awgChannelUi)
            self.settings.channelSettingsList[awgChannelUi.channel]['segmentTreeState'] = awgChannelUi.segmentView.saveTreeState()
        self.config[self.configname+'.state'] = self.saveState()
        self.config[self.configname+'.pos'] = self.pos()
        self.config[self.configname+'.size'] = self.size()
        self.config[self.configname+'.isMaximized'] = self.isMaximized()
        self.config[self.configname+'.isVisible'] = self.isVisible()
        self.config[self.configname+'.dockAreaState'] = self.area.saveState()
        self.config[self.configname+'.settingsDict'] = self.settingsDict
        self.config[self.configname+'.settingsName'] = self.settingsName
        self.config[self.configname+'.autoSave'] = self.autoSave
        self.config[self.configname+'.recentFiles'] = self.recentFiles
        self.config[self.configname+'.lastDir'] = self.lastDir

    def onRemove(self):
        """Remove current settings from combo box"""
        name = str(self.settingsComboBox.currentText())
        if name in self.settingsDict:
            self.settingsDict.pop(name)
            self.settingsName = list(self.settingsDict.keys())[0] if self.settingsDict else ''
            with BlockSignals(self.settingsComboBox) as w:
                self.settingsModel.setStringList( sorted(self.settingsDict.keys()) )
                w.setCurrentIndex(w.findText(self.settingsName))
            self.onLoad(self.settingsName)

    def onReload(self):
        """Reload settings"""
        name = str(self.settingsComboBox.currentText())
        self.onLoad(name)
       
    def onLoad(self, name):
        """load settings"""
        for channelUi in self.awgChannelUiList:
            self.settings.channelSettingsList[channelUi.channel]['segmentTreeState'] = channelUi.segmentView.saveTreeState()
        name = str(name)
        if name in self.settingsDict:
            self.settingsName = name
            self.tableModel.beginResetModel()
            [channelUi.segmentModel.beginResetModel() for channelUi in self.awgChannelUiList]
            self.settings.update(self.settingsDict[self.settingsName])
            self.programmingOptionsTable.setParameters( self.device.parameters() )
            self.saveButton.setEnabled(False)
            with BlockSignals(self.filenameComboBox) as w:
                w.setCurrentIndex(w.findText(os.path.basename(self.settings.filename)))
            with BlockSignals(self.cacheDepthSpinBox) as w:
                w.setValue(self.settings.cacheDepth)
            for channelUi in self.awgChannelUiList:
                channelUi.waveform.updateDependencies()
                channelUi.plotCheckbox.setChecked(self.settings.channelSettingsList[channelUi.channel]['plotEnabled'])
                with BlockSignals(channelUi.styleComboBox) as w:
                    w.setCurrentIndex(self.settings.channelSettingsList[channelUi.channel]['plotStyle'])
                channelUi.segmentModel.root = self.settings.channelSettingsList[channelUi.channel]['segmentDataRoot']
                channelUi.replot()
            self.onDependenciesChanged()
            self.saveButton.setEnabled(False)
            self.tableModel.endResetModel()
            [channelUi.segmentModel.endResetModel() for channelUi in self.awgChannelUiList]
            for channelUi in self.awgChannelUiList:
                channelUi.segmentView.restoreTreeState(self.settings.channelSettingsList[channelUi.channel]['segmentTreeState'])

    def onAutoSave(self, checked):
        """autosave is changed"""
        self.autoSave = checked
        self.saveButton.setEnabled( not checked )
        self.saveButton.setVisible( not checked )
        self.reloadButton.setEnabled( not checked )
        self.reloadButton.setVisible( not checked )
        if checked:
            self.onSave()

    def onValue(self, var=None, value=None):
        """variable value is changed in the table"""
        self.saveIfNecessary()
        self.replot()

    def evaluate(self, name):
        """re-evaluate the text in the tableModel (happens when a global changes)"""
        self.tableModel.evaluate(name)
        self.programmingOptionsTable.evaluate(name)

    def refreshVarDict(self):
        """refresh the variable dictionary by checking all waveform dependencies"""
        allDependencies = set()
        [channelUi.waveform.updateDependencies() for channelUi in self.awgChannelUiList]
        [allDependencies.update(channelUi.waveform.dependencies) for channelUi in self.awgChannelUiList]
        default = lambda varname:{'value':Q(1, 'us'), 'text':None} if varname.startswith('Duration') else {'value':Q(0), 'text':None}
        deletions = [varname for varname in self.settings.varDict if varname not in allDependencies]
        [self.settings.varDict.pop(varname) for varname in deletions] #remove all values that aren't dependencies anymore
        [self.settings.varDict.setdefault(varname, default(varname)) for varname in allDependencies] #add missing values
        self.settings.varDict.sort(key = lambda val: -1 if val[0].startswith('Duration') else ord( str(val[0])[0] ))
        self.varDictChanged.emit(self.varAsOutputChannelDict)
        for channelUi in self.awgChannelUiList:
            channelUi.replot()

    def onDependenciesChanged(self, channel=None):
        """When dependencies change, refresh all variables"""
        self.tableModel.beginResetModel()
        self.refreshVarDict()
        self.tableModel.endResetModel()
        self.saveIfNecessary()

    def onFilename(self, basename):
        """filename combo box is changed. Open selected file"""
        basename = str(basename)
        filename = self.recentFiles[basename]
        if os.path.isfile(filename) and filename!=self.settings.filename:
            self.openFile(filename)

    def onRemoveFile(self):
        """Remove file button is clicked. Remove filename from combo box."""
        text = str(self.filenameComboBox.currentText())
        index = self.filenameComboBox.findText(text)
        if text in self.recentFiles:
            self.recentFiles.pop(text)
        with BlockSignals(self.filenameComboBox) as w:
            self.filenameModel.setStringList(list(self.recentFiles.keys()))
            w.setCurrentIndex(-1)
            self.onFilename(w.currentText())

    def onNewFile(self):
        """New button is clicked. Pop up dialog asking for new name, and create file."""
        filename, _ = QtWidgets.QFileDialog.getSaveFileName(self, 'New File', self.lastDir, 'YAML (*.yml)')
        if filename:
            self.lastDir, basename = os.path.split(filename)
            self.recentFiles[basename] = filename
            self.settings.filename = filename
            with BlockSignals(self.filenameComboBox) as w:
                self.filenameModel.setStringList(list(self.recentFiles.keys()))
                w.setCurrentIndex(w.findText(basename))
            self.onSaveFile()

    def onOpenFile(self):
        """Open file button is clicked. Pop up dialog asking for filename."""
        filename, _ = QtWidgets.QFileDialog.getOpenFileName(self, 'Select File', self.lastDir, 'YAML (*.yml)')
        if filename:
            self.openFile(filename)

    def openFile(self, filename):
        """Open the file 'filename'"""
        if os.path.exists(filename):
            self.lastDir, basename = os.path.split(filename)
            self.recentFiles[basename] = filename
            self.settings.filename = filename
            with BlockSignals(self.filenameComboBox) as w:
                self.filenameModel.setStringList(list(self.recentFiles.keys()))
                w.setCurrentIndex(w.findText(basename))
            with open(filename, 'r') as f:
                yamldata = yaml.load(f)
            variables = yamldata.get('variables')
            channelData = yamldata.get('channelData')
            self.tableModel.beginResetModel()
            [channelUi.segmentModel.beginResetModel() for channelUi in self.awgChannelUiList]
            if channelData:
                for channelUi in self.awgChannelUiList:
                    if channelUi.channel < len(channelData):
                        self.settings.channelSettingsList[channelUi.channel]['segmentDataRoot'] = self.convertListToNodes(channelData[channelUi.channel], isRoot=True)
                        channelUi.segmentModel.root = self.settings.channelSettingsList[channelUi.channel]['segmentDataRoot']
            if variables:
                for varname, vardata in list(variables.items()):
                    self.settings.varDict.setdefault(varname, dict())
                    self.settings.varDict[varname]['value'] = Q(vardata['value'], vardata['unit'])
                    self.settings.varDict[varname]['text'] = vardata['text']
            for channelUi in self.awgChannelUiList:
                channelUi.waveform.updateDependencies()
                channelUi.replot()
            self.onDependenciesChanged()
            self.tableModel.endResetModel()
            [channelUi.segmentModel.endResetModel() for channelUi in self.awgChannelUiList]
            [channelUi.segmentView.expandAll() for channelUi in self.awgChannelUiList]
        else:
            logging.getLogger(__name__).warning("file '{0}' does not exist".format(filename))
            if filename in self.recentFiles:
                del self.recentFiles[filename]
                with BlockSignals(self.filenameComboBox) as w:
                    self.filenameModel.setStringList(list(self.recentFiles.keys()))
                    w.setCurrentIndex(-1)

    def convertNodeToList(self, node):
        nodeList = []
        for childNode in node.children:
            if childNode.nodeType==nodeTypes.segment:
                nodeList.append( {'equation':childNode.equation,
                                  'duration':childNode.duration,
                                  'enabled':childNode.enabled}
                                 )
            elif childNode.nodeType==nodeTypes.segmentSet:
                nodeList.append( {'repetitions':childNode.repetitions,
                                  'enabled':childNode.enabled,
                                  'segments':self.convertNodeToList(childNode)}
                                 )
        return nodeList

    def convertListToNodes(self, data, parent=None, enabled=True, repetitions=None, isRoot=False):
        node = AWGSegmentNode(parent=None) if isRoot else AWGSegmentSet(parent=parent, enabled=enabled, repetitions=repetitions)
        for segment in data:
            if 'duration' in segment:
                childNode = AWGSegment(parent=node,
                                       equation=segment['equation'],
                                       duration=segment['duration'],
                                       enabled=segment['enabled'])
                node.children.append(childNode)
            elif 'repetitions' in segment:
                segmentSet = self.convertListToNodes(segment['segments'], parent=node, enabled=segment['enabled'], repetitions=segment['repetitions'])
                node.children.append(segmentSet)
            else:
                logging.getLogger(__name__).error("Unable to convert list to nodes")
        return node

    def onSaveFile(self):
        """Save button is clicked. Save data to segment file"""
        channelData = []
        for channelSettings in self.settings.channelSettingsList:
            segmentData = self.convertNodeToList(channelSettings['segmentDataRoot'])
            channelData.append(segmentData)
        yamldata = {'channelData': channelData}
        variables={varname:
                             {'value':float(varValueTextDict['value'].toStringTuple()[0]),
                              'unit':varValueTextDict['value'].toStringTuple()[1],
                              'text':varValueTextDict['text']}
                         for varname, varValueTextDict in list(self.settings.varDict.items())}
        yamldata.update({'variables':variables})
        with open(self.settings.filename, 'w') as f:
            yaml.dump(yamldata, f, default_flow_style=False)

    def onReloadFile(self):
        self.openFile(self.settings.filename)

    @QtCore.pyqtProperty(dict)
    def varAsOutputChannelDict(self):
        """dict of output channels, for use in scans"""
        for varname in self.settings.varDict:
            if varname not in self._varAsOutputChannelDict:
                self._varAsOutputChannelDict[varname] = VarAsOutputChannel(self, varname, self.globalDict)
        deletions = [varname for varname in self._varAsOutputChannelDict if varname not in self.settings.varDict]
        [self._varAsOutputChannelDict.pop(varname) for varname in deletions] #remove all values that aren't dependencies anymore
        return self._varAsOutputChannelDict

    def close(self):
        self.saveConfig()
        numTempAreas = len(self.area.tempAreas)
        for i in range(numTempAreas):
            if len(self.area.tempAreas) > 0:
                self.area.tempAreas[0].win.close()
        super(AWGUi, self).close()