コード例 #1
0
ファイル: graphs.py プロジェクト: wepiha/nzxqt
    def __init__(self, parent: PlotWidget, data: list, maxY: int):
        super().__init__()

        self.plot = pg.PlotDataItem()
        self.plot._name = 'graph'

        parent.showAxis('bottom', False)
        parent.setLimits(
            yMin=-3,
            #xMax = 60,
            yMax=maxY - 3,
            maxXRange=60,
            minYRange=maxY,
            maxYRange=maxY)

        highlight = parent.palette().color(QPalette.Highlight)

        self.plot.setPen(pg.mkPen(highlight, width=2))
        self.plot.setBrush(highlight.darker())
        self.plot.setFillLevel(-1.0)
        self.plot.setData(np.zeros(60))  # + int(data))

        self.plot.append_data = self.append_data

        parent.getViewBox().setMouseEnabled(False)
        # prevent mouse wheel event
        parent.getViewBox().wheelEvent = lambda event: None
        parent.getViewBox().hoverEvent = self.mouse_hover
        parent.addItem(self.plot)
コード例 #2
0
ファイル: zoomnupdate3.py プロジェクト: lishuwen88/pqg_stuff
class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.setWindowTitle('Micromouse maze simulator')
        self.resize(600, 600)

        frame = QtWidgets.QFrame()
        layout = QtWidgets.QVBoxLayout(frame)

        self.graphics = PlotWidget()
        self.graphics.setAspectLocked()
        self.item = QtWidgets.QGraphicsRectItem(0, 0, 1, 1)
        self.item.setBrush(mkBrush('r'))
        self.item.setPen(mkPen(None))
        self.graphics.addItem(self.item)

        self.graphics.setRange(rect=QtCore.QRectF(-10, -10, 20, 20))

        self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal)
        self.slider.setSingleStep(1)
        self.slider.setPageStep(10)
        self.slider.setRange(0, 10)
        self.slider.setTickPosition(QtWidgets.QSlider.TicksAbove)
        self.slider.valueChanged.connect(self.slider_value_changed)
        self.slider.setValue(1)

        layout.addWidget(self.graphics)
        layout.addWidget(self.slider)

        self.setCentralWidget(frame)

    def slider_value_changed(self, value):
        self.item.setPos(value, 0)
コード例 #3
0
    def __init__(self):
        super().__init__()

        grid_layout = QGridLayout()
        self.setLayout(grid_layout)

        timer = QTimer(self)
        timer.timeout.connect(self.update_data)
        timer.start(1000)

        temp_title = QLabel(
            text='Tempture:',
            alignment=Qt.AlignCenter,
            styleSheet=TITLE_STYLES,
        )
        grid_layout.addWidget(temp_title)
        self.temp_data = PlotDataItem(temps)
        temp_widget = PlotWidget()
        temp_widget.addItem(self.temp_data)
        temp_widget.setXRange(0, max_history)
        temp_widget.setYRange(-10, 60)
        grid_layout.addWidget(temp_widget)

        fan_title = QLabel(
            text='Fan',
            alignment=Qt.AlignCenter,
            styleSheet=TITLE_STYLES,
        )
        grid_layout.addWidget(fan_title)
        self.fan_data = PlotDataItem(fans)
        fan_widget = PlotWidget()
        fan_widget.addItem(self.fan_data)
        fan_widget.setXRange(0, max_history)
        fan_widget.setYRange(0, 100)
        grid_layout.addWidget(fan_widget)

        last_log_title = QLabel(
            text='Lastest Event',
            alignment=Qt.AlignCenter,
            styleSheet=TITLE_STYLES,
        )
        grid_layout.addWidget(last_log_title)
        self.last_log = QLabel()
        self.last_log.resize(WINDOW_HEIGHT, WINDOW_WIDTH)
        self.last_log.setStyleSheet('font-weight: bold;'
                                    'background-color: grey;')
        grid_layout.addWidget(self.last_log)

        logs_title = QLabel(
            text='Event History',
            alignment=Qt.AlignCenter,
            styleSheet=TITLE_STYLES,
        )
        grid_layout.addWidget(logs_title)
        self.logs = QPlainTextEdit(self)
        self.logs.resize(WINDOW_HEIGHT, WINDOW_WIDTH)
        self.logs.resize(400, 200)
        grid_layout.addWidget(self.logs)

        self.setWindowTitle('Screen')
コード例 #4
0
class FigureWidget(QWidget):

    def __init__(   self, title=f"Figure", yRange=[-2, 6], \
                    xdata=[], ydata=[], \
                    color=20 \
                ):
        super().__init__()
        self.title = f'<h3> {title} </h3>'
        
        self.color = color
        self.x_data = np.array(xdata)
        self.y_data = np.array(ydata)
        self.y_min, self.y_max = yRange[0] , yRange[1]
        self.initFigure()

    
    def initFigure(self):

        # Configure Layout
        self.layout_model = QGridLayout()
        self.setLayout( self.layout_model )

        # Figure title is 1x3 (row x col) excel cell
        self.TITLE = QLabel(text=self.title)
        self.TITLE.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.TITLE.setAlignment(QtCoreQtClass.AlignCenter)
        self.layout_model.addWidget(self.TITLE, 0, 0, 1, 3)
        self.layout_model.setRowStretch(0, 1)

        #Figure size is 4x3 (row x col) excel cell
        self.Figure = PlotWidget()
        self.Figure.setYRange(self.y_min, self.y_max)
        self.graph = PlotCurveItem(pen = self.color )

        #plot initial data
        self.graph.setData(self.x_data, self.y_data)
        self.Figure.addItem(self.graph)

        # add to main figure widget & resize the grid layout
        self.layout_model.addWidget(self.Figure, 1, 0, 4, 3)
        for n in range(4):
            self.layout_model.setRowStretch(n+1, 7)
    
    def PlotData(self, x_data, y_data):
        self.x_data = x_data
        self.y_data = y_data

        self.graph.setData(self.x_data, self.y_data)
コード例 #5
0
ファイル: graphs.py プロジェクト: wepiha/nzxqt
    def __init__(self, parent: PlotWidget, data: list, staticPos=None):
        super().__init__()

        self.plotWidget = parent

        # adds _name attribute similar tto those in plotItem.items
        self._name = 'graph'
        self.staticPos = staticPos

        self.dragPoint = None
        self.dragOffset = None

        self.setData(pos=np.stack(data))

        parent.addItem(pg.TextItem())

        # adds pg.GraphItem to the parent PlotItems
        parent.addItem(self)
コード例 #6
0
    def on_pushButton_3_clicked(self):
        """
        Slot documentation goes here.
        """
        # answers = []
        # for answer in db['question_'+str(self.index)].find():
        #     text = answer['content'].replace('\n', '')
        #     if 5 < len(text) < 100:
        #         answers.append(text)
        answers = [
            answer['content'].replace('\n', '')
            for answer in db['question_' + str(self.index)].find()
        ]
        Line1 = InfiniteLine(pos=0, pen=(255, 0, 0), angle=0, movable=False)
        Line2 = InfiniteLine(pos=0.5, pen=(0, 0, 255), angle=0, movable=False)
        Line3 = InfiniteLine(pos=1, pen=(0, 255, 0), angle=0, movable=False)
        import sys
        start = perf_counter()
        data = LSTM.get_result(answers,
                               vec_path=sys.path[0] + '/lstm/vec_lstm.pkl',
                               model_path=sys.path[0] + '/lstm/lstmModel.pkl')
        end = perf_counter()
        print('情感分析总用时:' + str(end - start) + 's')
        tricks = [(0, '消极'), (0.5, '中立'), (1, '积极')]
        strAxis = AxisItem(orientation='left', maxTickLength=3)
        strAxis.setTicks([
            tricks,
        ])
        visitor_count_plot = PlotWidget(axisItems={'left': strAxis},
                                        background=None)
        visitor_count_plot.plot(y=data, pen=None, symbol='o')
        visitor_count_plot.showAxis('bottom', False)
        visitor_count_plot.addItem(Line1)
        visitor_count_plot.addItem(Line2)
        visitor_count_plot.addItem(Line3)
        visitor_count_plot.setObjectName("tab")

        # visitor_count_plot.enableAutoRange('x', x_axis_scale)
        self._add_analysis_tab(visitor_count_plot, '情感分析')
        self.pushButton_3.setEnabled(False)
コード例 #7
0
class clsDataView(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()

        # 类成员变量初始化
        self.colorDex = ['#7CFC00', '#B22222', '#E0FFFF', '#FFFF00', '#66FF00']

        self.lPlottedItems = []         # list of plotItems in the dataplot area
        self.currentPlotWin = ''        # keep current selected plot window for next curve plotting
        self.curLabelofYvalue = None          # the label of Y value in current plot area
        self.lPlotWindows = ['Plot1']            # list of plot window
        self.lViewBoxes = []              # list of View box corresponding to the plotitem
        self.lAxisItems = []           # list of axis item of the layout of plotItem
        self.lPlottedCurves = []            # list of plotCurves of each plotItem
        self.lDataFileName = []          # data file name list
        self.shortfname = ''           # data file name without path
        self.bPlotted = False           # not curve is plotted   - could be replaced by len(lPlotItems) > 1
        self.dataInRange_x = []           # keep the x ['TIME'] of data in range  - first curve plotted
        self.dataInRange_y = []           # keep the y of data in range  - first curve plotted

        self.lTestDATA = []      # the test data to be reviewed, each item is a class of data structure
                                    #  [testData1, testData2 ...]
                                    #  [(filename, column name, dataframe of data)
        self.parColPlotted = []           # parameter column in plotting

        self.minTimestamp = 1514764800.0      # the minimum of 20180101 08:00:00, ie. 1514764800.0 = datetime.datetime.strptime('2018-1-1 8:00:0', '%Y-%m-%d %H:%M:%S').timestamp()
        self.maxTimestamp = 1514800800.0 # datetime.strptime('2018-1-1 18:00:0', '%Y-%m-%d %H:%M:%S').timestamp()
        self.minYvalue = -20000
        self.maxYvalue = 20000

            # r'C:\onedrive\OneDrive - Honeywell\VPD\parameters code.csv'
        self.dataparam = dataParam(self.resource_path('parameters_code.csv'))   # data parameter definition
        #self.dataparam = dateParam()
        paramlist = self.dataparam.getParamName()
        #self.dataparam.getParamInfo('ABCVIINR', 'paramDesc')
        #self.dfData = pd.DataFrame()    # pandas dataframes to be plot

        # pyqtGraph 相关设置,必须要在self.setupUi之前
        setConfigOption('background', 'w')  # before loading widget

        # # set the time axis of X
        ### TODO: need to comment the self.dataplot line in the mainUI.py if it is recreated
        ###        or there is a error the plot widget being with no name of Plot1
        xAxis = self.TimeAxisItem(orientation='bottom')
        self.dataPlot = PlotWidget(self, axisItems={'bottom': xAxis}, name='Plot1')  ### TODO: need to comment the self.dataplot line in the mainUI.py if it is recreated

        self.setupUi(self)
        self.initUI()


        self.show()
        #self.showMaximized()   # max the window


    def initUI(self):

        # 添加打开菜单
        selFileAction = QAction('&Open', self)  # QAction(QIcon('open.png'), '&Open', self)
        selFileAction.setShortcut('Ctrl+O')
        selFileAction.setStatusTip('Open new File')
        selFileAction.triggered.connect(self.openFile)     # open data file
        selFileAction.setIcon(QIcon(self.resource_path('import.png')))

        exitAction = QAction('&Exit', self)    #QtGui.QAction(QIcon('exit.png'), '&Exit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit the application')
        #exitAction.triggered.connect(QtGui.qApp.quit)
        exitAction.triggered.connect(self.exitAPP)     # exit the application
        exitAction.setIcon(QIcon(self.resource_path('exit.png')))

        clearAction = QAction('Clear', self)   # QtGui.QAction(QIcon('Clear.png'), 'Clear', self)
        clearAction.triggered.connect(self.clearPlotArea)
        clearAction.setIcon(QIcon(self.resource_path('clear.png')))

        addPlotAction = QAction( 'Add a Plot', self)  #QtGui.QAction(QIcon('Addplot.png'), 'Add a Plot', self)
        addPlotAction.triggered.connect(self.addPlotAera)
        addPlotAction.setIcon(QIcon(self.resource_path('addplot.png')))

        removePlotAction = QAction('Remove the Plot', self) # QtGui.QAction(QIcon('Addplot.png'), 'Remove a Plot', self)
        removePlotAction.triggered.connect(self.removeDataPlotWin)
        removePlotAction.setIcon(QIcon(self.resource_path('remvplot.png')))

        viewAllAction = QAction("View All", self)
        viewAllAction.triggered.connect(self.autoRangeAllWins)
        viewAllAction.setIcon(QIcon(self.resource_path('viewall.png')))

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')         # add menu File
        fileMenu.addAction(selFileAction)            # link menu bar to openfile action with a menu item
        fileMenu.addAction(exitAction)               # add menu item exit

        plotMenu = menubar.addMenu("Plot")           # add menu Plot
        plotMenu.addAction(clearAction)               # add menu item of 'Clear' plot
        plotMenu.addAction(addPlotAction)             # add menu item of 'Add a Plot'
        plotMenu.addAction(removePlotAction)          # add menu item of 'Add a Plot'

        helpMenu = menubar.addMenu("Help")  # add menu help
        helpAction = QAction('?', helpMenu)
        helpAction.triggered.connect(self.helpme)
        helpMenu.addAction(helpAction)

        toolBar = self.addToolBar("Open")
        toolBar.addAction(selFileAction)             # link tool bar to openfile action

        toolBar.addAction(clearAction)
        toolBar.addAction(addPlotAction)
        toolBar.addAction(removePlotAction)
        toolBar.addAction(viewAllAction)




        # toolBar = self.addToolBar('Exit')
        # toolBar.addAction(selExitAction)  # link menu bar to openfile action

        # 设置dataPlot  class: PlotWidget
        self.dataPlot.plotItem.showGrid(True, True, 0.5)
        #self.dataPlot.plotItem.addLegend()

        self.dataPlot.setAutoVisible(y=True)


        # 设置treeWidget的相关  class: QTreeWidget
        self.treeWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.treeWidget.customContextMenuRequested.connect(self.showContextMenu)
        self.treeWidget.treeContextMenu = QMenu(self)
        self.actionA = self.treeWidget.treeContextMenu.addAction(u'Plot')
        self.actionA.triggered.connect(
            lambda: self.plotData(self.currSelctPlotWgt, self.treeWidget.selectedItems()))
        self.treeWidget.setColumnCount(4)
        self.treeWidget.setHeaderLabels(['#', 'Parameter', 'Parameter Name', 'Unit'])
        self.treeWidget.setColumnWidth(0, 10)
        self.treeWidget.setColumnWidth(1, 50)
        self.treeWidget.setColumnWidth(2, 100)

        ### drag and drop
        self.treeWidget.setDragDropMode(self.treeWidget.DragOnly)


        # set up context menu of list widget
        self.listWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.listWidget.customContextMenuRequested.connect(self.showListContextMenu)
        self.listWidget.listContextMenu = QMenu(self)
        self.actionB = self.listWidget.listContextMenu.addAction(u'Remove')
        self.actionB.triggered.connect(
            lambda: self.removeItemInPlot(self.listWidget.selectedItems()))


        #################### get the test data from the import window
        self.winImpData = clsImportData(self.dataparam, self.lTestDATA)     # instance of the ImportData window

        # # x axis for time
        # xAxis = self.TimeAxisItem("bottom")
        xAxis = self.dataPlot.plotItem.axes['bottom']['item']
        # plotitem and viewbox
        ## at least one plotitem is used whioch holds its own viewbox and left axis
        viewBox = self.dataPlot.plotItem.vb  # reference to viewbox of the plotitem
        viewBox.scaleBy(y=None)

        # # link x axis to view box
        xAxis.linkToView(viewBox)

        self.dataPlot.plotItem.scene().sigMouseMoved.connect(self.mouseMove)
        #self.dataPlot.plotItem.scene().sigMouseClicked.connect(self.mouseClick)

        # self.dataPlot.HoverEnterEvent = self.hoverEnterEvent

        ## drag and drop
        # self.dataPlot.dragEnterEvent = self.dragEnterEvent
        # self.dataPlot.plotItem.setAcceptDrops(True)
        # self.dataPlot.plotItem.dropEvent = self.dropEvent


        vLine = InfiniteLine(angle=90, movable=False, name='vline')
        hLine = InfiniteLine(angle=0, movable=False, name='hline')

        self.dataPlot.addItem(vLine, ignoreBounds=True)
        self.dataPlot.addItem(hLine, ignoreBounds=True)

        # set the default plot range
        self.dataPlot.setXRange(self.minTimestamp,self.maxTimestamp,padding=20)
        self.dataPlot.setYRange(-10, 10, padding=20)

        self.dataPlot.plotItem.getViewBox().setLimits()

        self.dataPlot.plotItem.getAxis('left').setWidth(w=30)
        self.dataPlot.plotItem.hideButtons()


        #self.dataPlot.plotItem.scene().sigMouseLeave.connect(self.mouseLeave) # ##TODO: cleaning house job
        self.dataPlot.installEventFilter(self)

        txtY_value = TextItem("", fill=(0, 0, 255, 80), anchor=(0,1),color='w')
        txtY_value.setParentItem(viewBox)

        self.curLabelofYvalue = txtY_value
        # #self.dataPlot.addItem(self.lableY_value)
        # labelY_value.setPos(self.minTimestamp,100.0)


        self.configPlotArea(self.dataPlot)

        # set current selection plot window background
        self.currSelctPlotWgt = self.dataPlot
        self.currSelctPlotWgt.setBackground(0.95)

    def eventFilter(self, source, event):
        #print (event.type())
        if event.type() == QEvent.Enter: #HoverEnter:
            #print("Enter " + source.plotItem.vb.name)
            self.currSelctPlotWgt.setBackground('default')
            self.currSelctPlotWgt = source
            self.currSelctPlotWgt.setBackground(0.95)
            plotAreaName = source.plotItem.vb.name
            #self.lPlottedItems.append({'Plot': plotWgtName, 'Curvename': curve_name, 'Filename': filename})

            labelofYvalueExisting = False
            plotAreaDirty = False
            for i in self.lPlottedItems:
                if i['Plot'] == plotAreaName:  # there is at least a curve in the plot
                    plotAreaDirty = True
                    break

            if plotAreaDirty:

                # get the lable of labelY_value
                for item in source.getViewBox().childItems():
                    if isinstance(item, graphicsItems.TextItem.TextItem):  # the text label is linked to the viewbox, not showing up
                        self.curLabelofYvalue = item
                        source.addItem(self.curLabelofYvalue)                 # add the text label to show it up
                        labelofYvalueExisting = True
                        break
                if not labelofYvalueExisting:
                    for item in source.plotItem.items:                      # the text label is in the plot item list
                        if isinstance(item, graphicsItems.TextItem.TextItem):
                            self.curLabelofYvalue = item
                            break


        if event.type() == QEvent.Leave: # and source is self.dataPlot:
            #print("Leave " + source.plotItem.vb.name)

            for item in source.plotItem.items:
                if isinstance(item, graphicsItems.TextItem.TextItem):
                    source.plotItem.removeItem(item)                    # remove the item
                    item.setParentItem(source.getViewBox())             # keep the link of the text label in the view box
                    break

            # move the hline to 0
            for iLine in source.items():  # loop for the hline
                if hasattr(iLine, 'name'):
                    if iLine.name() == 'hline':
                        iLine.setPos(self.minTimestamp)
                        break

        # print(event.type())
        # if event.type() == QEvent.GraphicsSceneDragEnter:
        #     self.currSelctPlotWgt.setBackground('default')
        #     self.currSelctPlotWgt = source
        #     self.currSelctPlotWgt.setBackground(0.95)

        return super(clsDataView,self).eventFilter(source,event)


    def configPlotArea(self, plotWin):

        vLine = InfiniteLine(angle=90, movable=False, name='vline')
        hLine = InfiniteLine(angle=0, movable=False, name='hline')
        plotWin.addItem(vLine, ignoreBounds=True)
        plotWin.addItem(hLine, ignoreBounds=True)
        #self.dataPlotRange.addItem(self.region, ignoreBounds=True)



    def showContextMenu(self):
        self.treeWidget.treeContextMenu.move(QCursor.pos())
        self.treeWidget.treeContextMenu.show()

    def dragEnterEvent(self, evt):
        evt.accept()

        # for i in range(self.dataPlotLayout.count()):
        #     plotAera = self.dataPlotLayout.itemAt(i).widget()
        #     print(plotAera.underMouse())
        #     if plotAera.underMouse():
        #         self.currSelctPlotWgt = plotAera
        #
        #         break

        # if self.currSelctPlotWgt.underMouse():

        # else:
        #     evt.ignore()

    def hoverEnterEvent(self,evet):
        pass

    def dropEvent(self, evt):
        #self.emit(mouseEnter event)
        #if self.currSelctPlotWgt.underMouse():
        for i in range(self.dataPlotLayout.count()):
            plotAera = self.dataPlotLayout.itemAt(i).widget()
            print(plotAera.plotItem.vb.name)
            print (plotAera.underMouse())
            if plotAera.underMouse():
                self.currSelctPlotWgt = plotAera
                self.plotData(plotAera, self.treeWidget.selectedItems())
                break

        self.plotData(self.currSelctPlotWgt, self.treeWidget.selectedItems())

    def showListContextMenu(self):
        self.listWidget.listContextMenu.move(QCursor.pos())
        self.listWidget.listContextMenu.show()


    def autoRangeAllWins(self):
        for i in range(self.dataPlotLayout.count()):
            plotItem = self.dataPlotLayout.itemAt(i).widget()

            plotItem.getViewBox().autoRange()

    def mouseClick(self, evnt):
        if self.currSelctPlotWgt:
            self.currSelctPlotWgt.setBackground('default')
            if evnt.currentItem is not None:
                try:
                    self.currSelctPlotWgt = evnt.currentItem._viewWidget()    # get the current selected widget
                    self.currSelctPlotWgt.setBackground(0.95)
                except Exception as e:
                    pass
                    #QMessageBox.critical(self, "Error", e.__str__())

    def clearPlotArea(self):
        #self.dataPlot.plotItem.clear()
        choice = QMessageBox.question(self, 'Plot1', "Remove all items in the first plot 1?",
                                            QMessageBox.Yes | QMessageBox.No)
        if choice == QMessageBox.Yes:

            for item in self.dataPlot.items():
                self.dataPlot.removeItem(item)

            lstitems = self.listWidget.findItems('Plot1', Qt.MatchStartsWith)
            if len(lstitems) > 0:
                for iitem in lstitems:
                    self.listWidget.takeItem(self.listWidget.row(iitem))

            for item in self.currSelctPlotWgt.scene().items():
                if isinstance(item, graphicsItems.LegendItem.LegendItem):  #  remove items in the scene including the legend
                    self.currSelctPlotWgt.scene().removeItem(item)

            #self.dataPlotRange.plotItem.clear()
            self.bPlotted = False
            self.configPlotArea(self.dataPlot)


    def addPlotAera(self):
        plotname = 'Plot' + str(len(self.lPlotWindows) + 1)
        axis = self.TimeAxisItem(orientation='bottom')
        vb = ViewBox()
        newdataPlot = PlotWidget(self, viewBox=vb, axisItems={'bottom': axis}, name = plotname)
        self.dataPlotLayout.addWidget(newdataPlot)
        self.configPlotArea(newdataPlot)

        newdataPlot.plotItem.scene().sigMouseClicked.connect(self.mouseClick)
        newdataPlot.plotItem.scene().sigMouseMoved.connect(self.mouseMove)

        ## drag and drop
        # newdataPlot.dragEnterEvent = self.dragEnterEvent
        # newdataPlot.plotItem.setAcceptDrops(True)
        # newdataPlot.plotItem.dropEvent = self.dropEvent

        # set the default plot range
        newdataPlot.setXRange(self.minTimestamp,self.maxTimestamp,padding=20)
        newdataPlot.setYRange(-10, 10, padding=20)

        newdataPlot.plotItem.getAxis('left').setWidth(w=30)
        newdataPlot.plotItem.hideButtons()

        newdataPlot.installEventFilter(self)

        newdataPlot.plotItem.showGrid(True, True, 0.5)

        vb.scaleBy(y=None)

        # make it the current selection plot area
        self.currSelctPlotWgt.setBackground('default')
        self.currSelctPlotWgt = newdataPlot  # set the current selection to plot1
        self.currSelctPlotWgt.setBackground(0.95)

        # link x axis to view box of the first data plot
        viewBox = self.dataPlot.plotItem.vb  # reference to viewbox of the plot 1
        axis.linkToView(viewBox)
        #axis.linkToView(vb)

        # Link plot 1 X axia to the view box
        lastplotItem = self.dataPlotLayout.itemAt(self.dataPlotLayout.count()-2).widget()
        lastplotItem.getViewBox().setXLink(newdataPlot)
        #lastplotItem.getViewBox().autoRange()

        txtY_value = TextItem("", fill=(0, 0, 255, 80), anchor=(0, 1), color='w')
        txtY_value.setParentItem(newdataPlot.plotItem.getViewBox())

        self.autoRangeAllWins()
        self.lPlotWindows.append(plotname)


    def removeDataPlotWin(self):
        curreSelctPlotWgtName = self.currSelctPlotWgt.getViewBox().name
        if curreSelctPlotWgtName != 'Plot1' and curreSelctPlotWgtName in self.lPlotWindows:  # can't delete plot1
            choice = QMessageBox.question(self, curreSelctPlotWgtName, "Remove the selected plot window?",
                                                QMessageBox.Yes | QMessageBox.No)
            if choice == QMessageBox.Yes:

                for item in self.currSelctPlotWgt.items():   # delete the items of the plot
                    self.currSelctPlotWgt.removeItem(item)

                lstitems = self.listWidget.findItems(curreSelctPlotWgtName, Qt.MatchStartsWith)  # delete the list in the list widget
                if len(lstitems) > 0:
                    for iitem in lstitems:
                        self.listWidget.takeItem(self.listWidget.row(iitem))

                for item in self.currSelctPlotWgt.scene().items():  #  remove everything in the scene including the legend
                    self.currSelctPlotWgt.scene().removeItem(item)



                self.dataPlotLayout.removeWidget(self.currSelctPlotWgt)
                self.currSelctPlotWgt.deleteLater()    #setHidden(True)     # hide the selected widget, should be deleted, to be updated with delect command
                self.currSelctPlotWgt = None
                self.lPlotWindows.remove(curreSelctPlotWgtName)    # remove the plot name from list of plot windows

                self.currSelctPlotWgt = self.dataPlot   # set the current selection to plot1
                self.currSelctPlotWgt.setBackground(0.95)

    def plotData(self, plotItem, selectedItems):
        '''selectedItems: items selected in tree view
           dfData: data frame of the selected data
        '''

        #plotItem = self.dataPlot.plotItem

        # viewbox = pg.ViewBox()
        # plotItem.scene().addItem(viewbox)

        #plotItem = self.currSelctPlotWgt
        plotItem.addLegend()

        #plotItem.getAxis('bottom').setPen(pg.mkPen(color='#000000', width=1))
        i = 0
        for iItem in selectedItems:
            if iItem.parent():     # not the root item
                filename = iItem.parent().text(1)    # get the parent item name - filename

                for iData in self.lTestDATA:          # find out the data from the data frame list by the filename
                    if filename == iData.fileName:
                        dfData = iData.data
                        break                       # break out of the loop for data


                data_head = iItem.text(1)           # get the column name of data for plotting
                curve_name = data_head + '>>' + iItem.text(2) + '>>' + iItem.text(3)    # parameter/parameter desc/unit

                # y axis
                data_2_plot = list(dfData[data_head])

                # get the list of time column, for x axis
                sTime = list(dfData['TIME'])

                # convert the time in string to date time object
                iTime = [self.sTimeToDateTime(j) for j in sTime]

                i += 1  # for color index use

                # example
                # pw.plot(x=[x.timestamp() for x in iTime ], y= list(df['BCVIIN']), pen = 'r')
                try:
                    plotcurve = PlotCurveItem(x=[x.timestamp() for x in iTime], y= data_2_plot, name = curve_name, pen=self.colorDex[i%5])
                    plotItem.addItem(plotcurve)
                except Exception as e:
                    QMessageBox.critical(self, "Error", "Error with data to plot.\n" + e.__str__())

                if not self.bPlotted:
                    self.bPlotted = True
                plotWgtName = self.currSelctPlotWgt.getViewBox().name
                if not plotWgtName: print("check the plotwidget definition in the mainUI.py, comment it!!!!")
                self.lPlottedItems.append({'Plot': plotWgtName, 'Curvename': curve_name, 'Filename': filename })
                self.listWidget.addItem(plotWgtName + '||' + curve_name + '||' + filename )

                # labl = QLabel(curve_name)
                # plotItem.addItem(labl)

                for lgditem in plotItem.scene().items():  # remove the legend
                    if isinstance(lgditem, graphicsItems.LegendItem.ItemSample):  #
                        lgditem.hide()   # hide the sample of legend  # plotItem.scene().items()[5].item is the curve itself
                        break

                self.autoRangeAllWins()


    def removeItemInPlot(self, selectedItem):
        try:
            if selectedItem[0]:
                [plotname,itemname,filename] = selectedItem[0].text().split('||')  #selectedItems()[0].text().split('||')

                for i in range(self.dataPlotLayout.count()):     # plot name = plot1 or plot2
                    plotWin = self.dataPlotLayout.itemAt(i).widget()
                    if plotname == plotWin.getViewBox().name:    # get the plot item
                        break

                for j in plotWin.plotItem.curves:    # get the curve item
                    curvename = j.name()
                    if curvename == itemname:
                        curveFound = True
                        break
                if curveFound:
                    plotWin.removeItem(j)               # delete the curve from the plot
                    #plotWin.scene().removeItem(plotWin.plotItem.legend)
                    for item in plotWin.scene().items():    # remove the legend
                        if isinstance(item, graphicsItems.LegendItem.LegendItem):      #isinstance(plotWin.scene().items()[6], pg.graphicsItems.LegendItem.LegendItem)
                            if item.items[0][1].text == curvename:                      # get the legend of the curve
                                plotWin.scene().removeItem(item)
                                break
                    self.listWidget.takeItem( self.listWidget.row(selectedItem[0]))    # remove the item from the list
                    for iPlottedItem in self.lPlottedItems:
                        if iPlottedItem['Filename'] == filename and iPlottedItem['Curvename'] == curvename:
                            self.lPlottedItems.remove(iPlottedItem)
                            break

                self.autoRangeAllWins()

        except Exception as e:
            print(e.__str__())



    def mouseMove(self, evt):
        #evtsender = self.sender()
        try:
            pos = evt  # get the point of mouse
            y_value = {}    # to keep the y values of all curves

        except Exception as e:
            print('exception @ mousemove 1' + e.__str__())

        if self.bPlotted:
            try:
                mousePoint = self.currSelctPlotWgt.plotItem.vb.mapSceneToView(pos)  # map the mouse position to the view position
                # mpOffset = plotWin.plotItem.vb.mapSceneToView(QPointF(0.0, 0.0))   # offset the mouse point
                x = self.minTimestamp
                timeIndex = datetime.fromtimestamp(x).strftime('%H:%M:%S:%f')[:12]
                if mousePoint.x() < self.minTimestamp - 3600 or mousePoint.x() > self.maxTimestamp + 2 * 3600:
                    #self.curLabelofYvalue.setPos(self.minTimestamp, mousePoint.y())
                    self.currSelctPlotWgt.plotItem.removeItem(self.curLabelofYvalue)  # remove the item
                    self.curLabelofYvalue.setParentItem(self.currSelctPlotWgt.getViewBox())
                    self.currSelctPlotWgt.plotItem.vb.autoRange()
                    return
                if mousePoint.y() < self.minYvalue or mousePoint.y() > self.maxYval:
                    #self.curLabelofYvalue.setPos(mousePoint.x(), self.minYvalue)
                    self.currSelctPlotWgt.plotItem.removeItem(self.curLabelofYvalue)  # remove the item
                    self.curLabelofYvalue.setParentItem(self.currSelctPlotWgt.getViewBox())
                    self.currSelctPlotWgt.plotItem.vb.autoRange()
                    #self.currSelctPlotWgt.scale(1,1,[{self.minTimestamp,self.minYvalue}])
                    return
            except Exception as e:
                pass

            try:
                #currentPlotArea = self.currSelctPlotWgt
                # move the vline in all plot area
                for i in range(self.dataPlotLayout.count()):  # loop for each plot area
                    plotWin = self.dataPlotLayout.itemAt(i).widget()
                    if plotWin.plotItem.sceneBoundingRect().contains(pos):  # mouse point in the plot aera
                        #print('Plot name: %s' % plotWin.getViewBox().name)
                        #print('view pos x: %0.1f + y: %0.1f' % (mousePoint.x(), mousePoint.y()))
                        # map the mouse position to the view position
                        mousePoint = plotWin.plotItem.vb.mapSceneToView(pos)
                        x = mousePoint.x()
                        # convert x coord from timestamp to time string
                        timeIndex = datetime.fromtimestamp(x).strftime('%H:%M:%S:%f')[:12]
                        #print('time: %s' % timeIndex)


                        for iLine in plotWin.items():  # loop for the vline
                            if hasattr(iLine, 'name'):
                                if iLine.name() == 'vline':
                                    iLine.setPos(mousePoint.x())
                                    break


                        #if plotWin.underMouse():  # check if the mouse is on the widget, True: current plot the mouse is in
                            #currentPlotArea = plotWin

                # move both hline in current plot area
                for iLine in self.currSelctPlotWgt.items():  # loop for the vline and hline
                    mousePoint = self.currSelctPlotWgt.plotItem.vb.mapSceneToView(pos)
                    if hasattr(iLine, 'name'):
                        if iLine.name() == 'hline':
                            iLine.setPos(mousePoint.y())
                            break

            except Exception as e:
                print('exception @ mousemove 2' + e.__str__())

            # get the y value of all plotted curves
            try:
                if self.lPlottedItems.__len__() > 0:
                    curr_Y = [round(mousePoint.y(),2)]
                    for iCurve in self.lPlottedItems:
                        plotname = iCurve['Plot']
                        filename = iCurve["Filename"]
                        curvename = iCurve["Curvename"].split('>>')[0]

                        for dataset in self.lTestDATA:
                            dfData = dataset.data
                            startTime = datetime.strptime('2018 ' + dfData['TIME'].iloc[0],
                                                          '%Y %H:%M:%S:%f').timestamp()
                            endTime = datetime.strptime('2018 ' + dfData['TIME'].iloc[-1],
                                                        '%Y %H:%M:%S:%f').timestamp()
                            rate = dataset.rate

                            if x > startTime and x < endTime:
                                row = round((x - startTime) * rate)  # the the row number
                                #print('row number: %d' % row)
                                y = dfData[curvename].iloc[row]  # dfData[curvename].iloc()[row]
                                #print('y: %f' % y)
                                y_value[curvename] = y  # keep the curve value in y to the list

                                if self.currSelctPlotWgt.getViewBox().name == plotname:  # the data set of current plot area
                                    curr_Y.append(round(y,2))

            except Exception as e:
                print('exception @ mousemove 3' + e.__str__())

            # display the y value of all curves
            try:
                self.labelTime.setText("<span style='font-size: 11pt'>Time=%s" % (timeIndex))

                if y_value:
                    # show the values of all curves shown in plots
                    self.labelValueY.setText("<span style='font-size: 11pt; color: red'>" + str(
                        ["%s=%0.1f" % (k, v) for k, v in y_value.items()]))
            except Exception as e:
                print('exception @ mousemove 4' + e.__str__())

            # show the label in current plot area

            try:
                if curr_Y.__len__() > 0:
                    # labelY_value = pg.TextItem("v")
                    # currentPlotArea.addItem(labelY_value)
                    # currentPlotArea.setPos(mousePoint.x(), mousePoint.y())
                    self.curLabelofYvalue.setText((''.join(str(e) + '\n' for e in curr_Y))[:-1])   # [:-1] to remove the last '\n'
                    self.curLabelofYvalue.setPos(mousePoint.x(), mousePoint.y())
                    #print(self.curLabelofYvalue.__str__)
                    #self.dataPlot.addItem(labelY_value)
            except Exception as e:
                print('exception @ mousemove 5' + e.__str__())



    def openFile(self):
        self.winImpData.exec_()  # Run the imp data window in modal
        self.treeUpdate()

    def exitAPP(self):
        choice = QMessageBox.question(self, 'Exit', "Close the application?",
                                           QMessageBox.Yes | QMessageBox.No)
        if choice == QMessageBox.Yes:
            sys.exit()
        else:
            pass

    def treeUpdate(self):
        QTreeWidget.clear(self.treeWidget)
        for tdataset in self.lTestDATA:
            fname = tdataset.fileName           #os.path.basename(self.winImpData.sDataFilePath)
            rate = tdataset.rate

            treeRoot = QTreeWidgetItem(self.treeWidget)
            treeRoot.setText(1, fname)
            treeRoot.setText(2, str(rate) + 'Hz')

            self.treeItem = tdataset.header  # list(self.winImpData.dfData)
            self.numTree = tdataset.column     #self.treeItem.__len__()

            for i in range(1, len(self.treeItem)):
                child = QTreeWidgetItem(treeRoot)
                child.setText(0, str(i))
                child.setText(1, self.treeItem[i])
                child.setText(2, self.dataparam.getParamInfo(self.treeItem[i],'paramDesc'))
                child.setText(3, self.dataparam.getParamInfo(self.treeItem[i],'unit'))

    def helpme(self):
        QMessageBox.information(self,'Wheel & Brake Test Data Explorer', 'Technical support:\nHON MS&C Shanghai.')

    ### for PyInataller use to bundle data file into one file
    def resource_path(self, relative_path):
        """ Get absolute path to resource, works for dev and for PyInstaller """
        if hasattr(sys, '_MEIPASS'):
            return path.join(sys._MEIPASS, relative_path)
        return path.join(path.abspath("."), relative_path)
        # base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
        # return os.path.join(base_path, relative_path)


    class TimeAxisItem(AxisItem): #### class TimeAxisItem is used for overloading x axis as time
        def tickStrings(self, values, scale, spacing):
            strns = []
            #rng = max(values) - min(values)    # values are timestamp of date
            #946656000 = datetime.strptime('2000', '%Y').timestamp() ,  handel dates after 2000 only
            # if min(values) < 946656000:  # Windows can't handle dates before 1970,
            #     # 1514764800.0 = datetime.datetime.strptime('2018-1-1 8:00:0', '%Y-%m-%d %H:%M:%S').timestamp()
            #     # 1514766600.0 = datetime.datetime.strptime('2018-1-1 8:30:0', '%Y-%m-%d %H:%M:%S').timestamp()
            #     #defaultValues = range(1514736000.0, 1514768400.0, 720)
            #
            #     return pg.AxisItem.tickStrings(self, values, scale, spacing)

            for x in values:
                try:
                    if x < 946656000: x += 946656000     ## handle time starting from 1/1/2000
                    strns.append(datetime.fromtimestamp(x).strftime('%H:%M:%S'))
                except ValueError:  ## Windows can't handle dates before 1970
                    strns.append('')

            return strns

            # show hour:minute:second on the x axis
            #return [datetime.fromtimestamp(value).strftime('%H:%M:%S') for value in values]
                # 946656000 = datetime.strptime('2000', '%Y').timestamp()


    def sTimeToDateTime(self, inTime):  # convert time from string to datetime object
        # inTime: '13:43:02:578' string type
        # outTime: 2018-01-01 13:43:02.578000  datetime object

        # '2018 ' + startTime, '%Y %H:%M:%S'
        #itime = inTime[:8] + "." + inTime[10:12]   # convert 13:43:02:578 to 13:43:02.578
        # add date (2018-01-01)to the TIME for the sake of format of datetime class. could use real date of the data created
        try:
            outTime = datetime.strptime('2018 ' + inTime, '%Y %H:%M:%S:%f')  # convert the time from string to the datetime format
        except Exception as e:
            QMessageBox.critical(self, "Error", "TIME format error.\n" + e.__str__())
            outTime = datetime.now()
        return outTime
コード例 #8
0
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1200, 850)

        # Main window
        self.centralwidget = QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        MainWindow.setCentralWidget(self.centralwidget)

        # Plot widget
        self.plotWidget = PlotWidget(self.centralwidget)
        self.plotWidget.setObjectName("PlotWidget")

        # Trails view
        self.trailsScene = QGraphicsScene()
        self.trailsView = QGraphicsView(self.trailsScene, self.centralwidget)
        self.trailsView.setObjectName("trailsView")

        # Heatmap view
        self.heatmapScene = QGraphicsScene()
        self.heatmapView = QGraphicsView(self.heatmapScene, self.centralwidget)
        self.heatmapView.setObjectName("heatmapView")

        # OpenGL widget
        self.openGLWidget = OpenGLWidget()
        self.openGLWidget.setObjectName("openGLView")

        # Stacked widget, combining plot widget and graphics view
        self.stackedWidget = QStackedWidget(self.centralwidget)
        self.stackedWidget.setGeometry(QRect(10, 10, 800, 800))
        self.stackedWidget.setObjectName("stackedWidget")
        self.stackedWidget.addWidget(self.plotWidget)
        self.stackedWidget.addWidget(self.trailsView)
        self.stackedWidget.addWidget(self.heatmapView)
        self.stackedWidget.addWidget(self.openGLWidget)

        # Perturbation title
        self.perturbationSlidersLabel = QLabel(self.centralwidget)
        self.perturbationSlidersLabel.setGeometry(QRect(960, 30, 170, 20))
        font = QFont()
        font.setPointSize(14)
        self.perturbationSlidersLabel.setFont(font)
        self.perturbationSlidersLabel.setObjectName("perturbation_title")

        # Perturbation 1
        self.horizontalSlider1 = QSlider(self.centralwidget)
        self.horizontalSlider1.setGeometry(QRect(920, 80, 270, 20))
        self.horizontalSlider1.setMaximum(100)
        self.horizontalSlider1.setOrientation(Qt.Horizontal)
        self.horizontalSlider1.setInvertedAppearance(False)
        self.horizontalSlider1.setObjectName("horizontal1Slider")
        self.horizontalSlider1.valueChanged.connect(self.slider1Changed)
        self.checkBox1 = QCheckBox(self.centralwidget)
        self.checkBox1.setGeometry(QRect(830, 80, 90, 20))
        self.checkBox1.setTristate(False)
        self.checkBox1.setObjectName("checkBox1")

        # Perturbation 2
        self.horizontalSlider2 = QSlider(self.centralwidget)
        self.horizontalSlider2.setGeometry(QRect(920, 130, 270, 20))
        self.horizontalSlider2.setMaximum(100)
        self.horizontalSlider2.setOrientation(Qt.Horizontal)
        self.horizontalSlider2.setInvertedAppearance(False)
        self.horizontalSlider2.setObjectName("horizontalSlider2")
        self.horizontalSlider2.valueChanged.connect(self.slider2Changed)
        self.checkBox2 = QCheckBox(self.centralwidget)
        self.checkBox2.setGeometry(QRect(830, 130, 90, 20))
        self.checkBox2.setObjectName("checkBox2")

        # Perturbation 3
        self.horizontalSlider3 = QSlider(self.centralwidget)
        self.horizontalSlider3.setGeometry(QRect(920, 180, 270, 20))
        self.horizontalSlider3.setMaximum(100)
        self.horizontalSlider3.setOrientation(Qt.Horizontal)
        self.horizontalSlider3.setInvertedAppearance(False)
        self.horizontalSlider3.setObjectName("horizontalSlider3")
        self.horizontalSlider3.valueChanged.connect(self.slider3Changed)
        self.checkBox3 = QCheckBox(self.centralwidget)
        self.checkBox3.setGeometry(QRect(830, 180, 90, 20))
        self.checkBox3.setObjectName("checkBox3")

        # Perturbation 4
        self.horizontalSlider4 = QSlider(self.centralwidget)
        self.horizontalSlider4.setGeometry(QRect(920, 230, 270, 20))
        self.horizontalSlider4.setMaximum(100)
        self.horizontalSlider4.setOrientation(Qt.Horizontal)
        self.horizontalSlider4.setInvertedAppearance(False)
        self.horizontalSlider4.setObjectName("horizontalSlider4")
        self.horizontalSlider4.valueChanged.connect(self.slider4Changed)
        self.checkBox4 = QCheckBox(self.centralwidget)
        self.checkBox4.setGeometry(QRect(830, 230, 90, 20))
        self.checkBox4.setObjectName("checkBox4")

        # Random perturbation button
        self.perturbSelectedButton = QPushButton(self.centralwidget)
        self.perturbSelectedButton.setGeometry(QRect(830, 300, 150, 50))
        self.perturbSelectedButton.setObjectName("perturbSelectedButton")
        self.perturbSelectedButton.setToolTip(
            "Randomly set all checked perturbations")
        self.perturbSelectedButton.clicked.connect(self.randChangeSelected)

        self.reset = QPushButton(self.centralwidget)
        self.reset.setGeometry(QRect(1000, 300, 110, 50))
        self.reset.setObjectName("reset_button")
        self.reset.setToolTip("Set all checked perturbations back to 0")
        self.reset.clicked.connect(self.resetSelected)

        # Menubar items
        self.menubar = QMenuBar(MainWindow)
        self.menubar.setGeometry(QRect(0, 0, 1285, 21))
        self.menubar.setObjectName("menubar")
        self.menuFile = QMenu(self.menubar)
        self.menuFile.setObjectName("menuFile")
        self.menuViews = QMenu(self.menubar)
        self.menuViews.setObjectName("menuViews")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.viewsBasic = QAction(MainWindow)
        self.viewsBasic.setObjectName("viewsBasic")
        self.viewsBasic.triggered.connect(lambda: self.switchWidget(0))
        self.viewsTrail = QAction(MainWindow)
        self.viewsTrail.setObjectName("viewsTrail")
        self.viewsTrail.triggered.connect(lambda: self.switchWidget(1))
        self.viewsHeatmap = QAction(MainWindow)
        self.viewsHeatmap.setObjectName("viewsHeatmap")
        self.viewsHeatmap.triggered.connect(lambda: self.switchWidget(2))
        self.viewsOpenGL = QAction(MainWindow)
        self.viewsOpenGL.setObjectName("viewsOpenGL")
        self.viewsOpenGL.triggered.connect(lambda: self.switchWidget(3))

        self.fileReset = QAction(MainWindow)
        self.fileReset.setObjectName("fileReset")
        # self.fileReset.action.connect(self.reset)
        self.fileSave = QAction(MainWindow)
        self.fileSave.setObjectName("fileSave")
        self.menuFile.addAction(self.fileReset)
        self.menuFile.addAction(self.fileSave)
        self.menuViews.addAction(self.viewsBasic)
        self.menuViews.addAction(self.viewsTrail)
        self.menuViews.addAction(self.viewsHeatmap)
        self.menuViews.addAction(self.viewsOpenGL)

        self.menubar.addAction(self.menuFile.menuAction())
        self.menubar.addAction(self.menuViews.menuAction())

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

    def retranslateUi(self, MainWindow):
        _translate = QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.checkBox1.setText(_translate("MainWindow", "Add constant"))
        self.checkBox2.setText(_translate("MainWindow", "Dim. removal"))
        self.checkBox3.setText(_translate("MainWindow", "Perturbation3"))
        self.checkBox4.setText(_translate("MainWindow", "Perturbation4"))
        self.perturbSelectedButton.setText(
            _translate("MainWindow", "Randomize selected"))
        self.reset.setText(_translate("MainWindow", "Reset"))
        self.perturbationSlidersLabel.setText(
            _translate("MainWindow", "Perturbation sliders"))

        self.menuFile.setTitle(_translate("MainWindow", "File"))
        self.menuViews.setTitle(_translate("MainWindow", "Views"))

        self.viewsBasic.setText(_translate("MainWindow", "Basic interface"))
        self.viewsBasic.setShortcut(_translate("MainWindow", "Ctrl+1"))
        self.viewsTrail.setText(_translate("MainWindow", "Trail interface"))
        self.viewsTrail.setShortcut(_translate("MainWindow", "Ctrl+2"))
        self.viewsHeatmap.setText(
            _translate("MainWindow", "Heat map interface"))
        self.viewsHeatmap.setShortcut(_translate("MainWindow", "Ctrl+3"))
        self.viewsOpenGL.setText(_translate("MainWindow", "OpenGL interface"))
        self.viewsOpenGL.setShortcut(_translate("MainWindow", "Ctrl+4"))

        self.fileReset.setText(_translate("MainWindow", "Reset"))
        self.fileReset.setShortcut(_translate("MainWindow", "Ctrl+R"))
        self.fileSave.setText(_translate("MainWindow", "Save"))
        self.fileSave.setShortcut(_translate("MainWindow", "Ctrl+S"))

    def switchWidget(self, index):
        self.stackedWidget.setCurrentIndex(index)
        print("Going to stacked widget index: " + str(index))
        # TODO: only compute intermediateDatasets if not already done so
        if index == 1:
            self.statusbar.showMessage(
                "Computing and predicting intermediate datasets per increment..."
            )
            self.computeIntermediateDatasets()
            self.statusbar.showMessage("Drawing trail map...")
            self.projectTrailMap()
            self.statusbar.showMessage("Trail map projected.")
        if index == 2:
            self.statusbar.showMessage(
                "Computing and predicting intermediate datasets per increment..."
            )
            self.computeIntermediateDatasets()
            self.statusbar.showMessage("Drawing heat map...")
            self.projectHeatMap()
            self.statusbar.showMessage("Heat map projected.")
        if index == 3:
            self.statusbar.showMessage(
                "Computing and predicting intermediate datasets per increment..."
            )
            self.computeIntermediateDatasets()
            self.statusbar.showMessage("Drawing trail map...")
            if self.predList:
                self.openGLWidget.paintTrailMapGL(self.predList, self.y_test,
                                                  self.class_colors)
            else:
                print("No data to create trail map with.")
                self.statusbar.showMessage("No data to create trail map with.")

    def computeIntermediateDatasets(self):
        # If no checkbox is checked
        if not self.checkBox1.isChecked() and not self.checkBox2.isChecked() and \
                not self.checkBox3.isChecked() and not self.checkBox4.isChecked():
            self.statusbar.showMessage(
                "No perturbation is selected. Please choose one of them.")
            return

        print("Computing intermediate datasets")
        # Perturb using the checked perturbation
        if self.checkBox1.isChecked():
            max_value = self.horizontalSlider1.value()
            self.dataset.interDataOfPerturb(1, max_value)
        if self.checkBox2.isChecked():
            max_value = self.horizontalSlider2.value()
            self.dataset.interDataOfPerturb(2, max_value)

        # Predict every dataset and save to predList
        self.predList = []
        for i in range(0, len(self.dataset.interDataset)):
            self.predList.append(
                self.model.predict(self.dataset.interDataset[i]))

    # Project a trail map using the data in predList
    def projectTrailMap(self):
        for j in range(len(self.predList[0])):
            pen = pg.mkPen(color=self.y_test[j], width=1)
            for i in range(len(self.predList) - 1):
                x1 = self.predList[i][j][0]
                y1 = self.predList[i][j][1]
                x2 = self.predList[i + 1][j][0]
                y2 = self.predList[i + 1][j][1]
                self.trailsScene.addLine(x1, y1, x2, y2, pen)

        # Fit trail map to screen
        # self.trailsScene.itemsBoundingRect()
        self.trailsView.fitInView(0, 0, 1, 1, Qt.KeepAspectRatio)

    def projectHeatMap(selfs):
        pass

    def replot(self):
        pred = self.model.predict(self.dataset.perturbed)
        items = pg.ScatterPlotItem(x=pred[:, 0],
                                   y=pred[:, 1],
                                   data=np.arange(len(self.dataset.perturbed)),
                                   pen='w',
                                   brush=self.brushes,
                                   size=10,
                                   hoverable=True,
                                   hoverPen=pg.mkPen(0, 0, 0, 255))
        self.plotWidget.clear()
        self.plotWidget.addItem(items)
        # Disable range adjustments
        self.plotWidget.setRange(None, (0, 1), (0, 1))

        self.plotWidget.setXRange(0, 1)

    def slider1Changed(self):
        new_value = self.horizontalSlider1.value()
        self.statusbar.showMessage(
            "Changed value of perturbation slider 1 to " + str(new_value))
        self.dataset.addConstantNoise(new_value)
        self.replot()

    def slider2Changed(self):
        new_value = self.horizontalSlider2.value()
        self.statusbar.showMessage(
            "Changed value of perturbation slider 2 to " + str(new_value))
        self.dataset.removeRandomDimensions(new_value)
        self.replot()

    def slider3Changed(self):
        new_value = self.horizontalSlider3.value()
        self.statusbar.showMessage(
            "Changed value of perturbation slider 3 to " + str(new_value))

    def slider4Changed(self):
        new_value = self.horizontalSlider4.value()
        self.statusbar.showMessage(
            "Changed value of perturbation slider 4 to " + str(new_value))

    def randChangeSelected(self):
        if self.checkBox1.isChecked():
            self.horizontalSlider1.setValue(
                randint(1, self.horizontalSlider2.maximum()))
        if self.checkBox2.isChecked():
            self.horizontalSlider2.setValue(
                randint(1, self.horizontalSlider2.maximum()))
        if self.checkBox3.isChecked():
            self.horizontalSlider3.setValue(
                randint(1, self.horizontalSlider3.maximum()))
        if self.checkBox4.isChecked():
            self.horizontalSlider4.setValue(
                randint(1, self.horizontalSlider4.maximum()))

    def resetSelected(self):
        if self.checkBox1.isChecked():
            self.horizontalSlider1.setValue(0)
        if self.checkBox2.isChecked():
            self.horizontalSlider2.setValue(0)
        if self.checkBox3.isChecked():
            self.horizontalSlider3.setValue(0)
        if self.checkBox4.isChecked():
            self.horizontalSlider4.setValue(0)

    def loadTestData(self, MainWindow):
        print("Loading dummy data...")
        x = np.random.normal(size=1000)
        y = np.random.normal(size=1000)

        brush = pg.mkBrush(50, 200, 50, 120)
        hoverBrush = pg.mkBrush(200, 50, 50, 200)
        items = pg.ScatterPlotItem(x=x,
                                   y=y,
                                   pen='w',
                                   brush=brush,
                                   size=15,
                                   hoverable=True,
                                   hoverBrush=hoverBrush)
        self.plotWidget.addItem(items)

    def loadData(self, MainWindow):
        print("Loading datasets...")
        X = np.load('data/X_mnist.npy')
        y = np.load('data/y_mnist.npy')
        label = "mnist-full"

        X_train, X_test, y_train, y_test = train_test_split(X,
                                                            y,
                                                            train_size=10000,
                                                            test_size=300,
                                                            random_state=420,
                                                            stratify=y)
        self.y_test = y_test

        # Class colors
        self.class_colors = [(0.890, 0.102, 0.110), (0.122, 0.471, 0.706),
                             (0.698, 0.875, 0.541), (0.200, 0.627, 0.173),
                             (0.984, 0.604, 0.600), (0.651, 0.808, 0.890),
                             (0.992, 0.749, 0.435), (1.000, 0.498, 0.000),
                             (0.792, 0.698, 0.839), (0.416, 0.239, 0.604),
                             (1.000, 1.000, 0.600), (0.694, 0.349, 0.147)]

        self.dataset = Dataset(X_test)

        print("Loading NNP model...")
        self.model = keras.models.load_model("NNP_model_" + label)

        pred = self.model.predict(X_test)
        self.brushes = []
        for label in y_test:
            color = self.class_colors[label]
            self.brushes.append(
                QBrush(QColor.fromRgbF(color[0], color[1], color[2])))

        items = pg.ScatterPlotItem(x=pred[:, 0],
                                   y=pred[:, 1],
                                   data=np.arange(len(X_test)),
                                   pen='w',
                                   brush=self.brushes,
                                   size=10,
                                   hoverable=True,
                                   hoverPen=pg.mkPen(0, 0, 0, 255))

        self.plotWidget.addItem(items)
コード例 #9
0
class MCClassroom(QWidget):
    def __init__(self, settings, server):
        super().__init__()

        self.server = server
        self.timer = QTimer()
        self.timer.timeout.connect(self.time_tick)

        self.settings = settings
        self.current_class = None
        self.current_students = []

        self.stack = QStackedLayout()
        self.setLayout(self.stack)

        # First page: connection instructions
        connect_widget = QWidget()
        connect_layout = QVBoxLayout(connect_widget)
        connect_layout.addStretch()
        connect_label = QLabel(
            "Open a world in Minecraft, open a terminal (press t), and type:",
            self)
        connect_layout.addWidget(connect_label)
        self.connect_command = f'/connect {server.get_ip()}:{PORT}'
        connect_command_box = QLineEdit(self.connect_command, self)
        connect_command_box.setReadOnly(True)
        connect_layout.addWidget(connect_command_box)
        connect_copy_button = QPushButton("Copy to Clipboard", self)
        connect_copy_button.clicked.connect(
            lambda: QApplication.clipboard().setText(self.connect_command))
        connect_layout.addWidget(connect_copy_button)
        connection_problems_button = QPushButton("Connection Problems?", self)
        connection_problems_button.clicked.connect(self.show_connection_help)
        connect_layout.addWidget(connection_problems_button)
        connect_layout.addStretch()
        self.stack.addWidget(connect_widget)

        # Main page
        main_col_widget = QWidget()
        columns = QHBoxLayout(main_col_widget)
        col_left = QVBoxLayout()
        col_mid = QVBoxLayout()
        col_right = QVBoxLayout()
        columns.addLayout(col_left)
        columns.addSpacing(10)
        columns.addLayout(col_mid)
        columns.addSpacing(10)
        columns.addLayout(col_right)
        self.stack.addWidget(main_col_widget)

        self.pause_button = self.setup_toggle_button(col_left,
                                                     self.server.pause_game,
                                                     'Un-pause',
                                                     self.server.unpause_game,
                                                     'Pause')
        button_size = self.pause_button.size()
        self.disable_chat_button = self.setup_toggle_button(
            col_left, self.server.disable_chat, 'Enable Chat',
            self.server.enable_chat, 'Disable Chat', button_size)
        self.allow_mobs_button = self.setup_toggle_button(
            col_left, self.server.disallow_mobs, 'Allow Mobs',
            self.server.allow_mobs, 'Disable Mobs', button_size)
        self.allow_destructiveobjects_button = self.setup_toggle_button(
            col_left, self.server.disallow_destructiveobjects,
            'Enable Destructive Items', self.server.allow_destructiveobjects,
            'Disable Destructive Items', button_size)
        self.allow_player_damage_button = self.setup_toggle_button(
            col_left, self.server.disallow_player_damage,
            'Enable Player Damage', self.server.allow_player_damage,
            'Disable Player Damage', button_size)
        self.allow_pvp_button = self.setup_toggle_button(
            col_left, self.server.disallow_pvp, 'Allow Player Fighting',
            self.server.allow_pvp, 'Disable Player Fighting', button_size)
        self.immutable_button = self.setup_toggle_button(
            col_left, self.server.immutable_world,
            'Enable World Modifications', self.server.mutable_world,
            'Disable World Modifications', button_size)
        self.weather_button = self.setup_toggle_button(
            col_left, self.server.perfect_weather, 'Disable Perfect Weather',
            self.server.imperfect_weather, 'Enable Perfect Weather',
            button_size)
        self.disable_potions_button = self.setup_toggle_button(
            col_left, self.server.disable_potions, 'Enable Potions',
            self.server.enable_potions, 'Disable Potions', button_size)

        # self.clear_potions_button = QPushButton('Clear All Potion Effects', self)
        # self.clear_potions_button.resize(button_size)
        # self.clear_potions_button.clicked.connect(lambda: self.server.clear_effects("@a"))
        # col_left.addWidget(self.clear_potions_button)

        self.teleport_button = QPushButton('Teleport Everyone to You', self)
        self.teleport_button.resize(button_size)
        self.teleport_button.clicked.connect(
            lambda: self.server.teleport_all_to("@s"))
        col_left.addWidget(self.teleport_button)

        self.disconnect_button = QPushButton('Disconnect', self)
        self.disconnect_button.resize(button_size)
        self.disconnect_button.clicked.connect(self.server.socket_disconnected)
        col_left.addWidget(self.disconnect_button)

        col_left.addStretch()

        self.version_label = QLabel(f'Version {VERSION}', self)
        self.version_label.setAlignment(Qt.AlignCenter)
        col_left.addWidget(self.version_label)

        self.feedback_button = QPushButton('Feedback/Bug report', self)
        self.feedback_button.resize(button_size)
        self.feedback_button.clicked.connect(
            lambda: QDesktopServices.openUrl(FEEDBACK_URL))
        col_left.addWidget(self.feedback_button)

        # Middle Column: Roll/Register
        self.classes_combo = QComboBox(self)
        class_names = self.settings.value("class_names", [])
        self.classes_combo.addItem("Select class")
        self.classes_combo.addItem("Add a class")
        self.classes_combo.addItem("Delete a class")
        self.classes_combo.addItems(class_names)
        self.classes_combo.currentTextChanged.connect(self.class_changed)
        col_mid.addWidget(self.classes_combo)

        self.users_table = QTableWidget(0, 2)
        self.users_table.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.users_table.setSizePolicy(
            QSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding))
        self.users_table.setFixedWidth(140)
        self.users_table.verticalHeader().hide()
        header = self.users_table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.Stretch)
        header.setSectionResizeMode(1, QHeaderView.ResizeToContents)
        header.hide()
        col_mid.addWidget(self.users_table)

        self.class_edit_button = QPushButton("Edit Class", self)
        col_mid.addWidget(self.class_edit_button)
        self.class_edit_button.clicked.connect(self.edit_class)

        self.chat_box = QPlainTextEdit(
            f'Minecraft Education Chat Logs {datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")}',
            self)
        self.chat_box.setReadOnly(True)
        col_right.addWidget(self.chat_box)

        self.chat_input = QLineEdit(self)
        self.chat_input.setPlaceholderText("Type chat here; enter to send")
        self.chat_input.returnPressed.connect(self.chat_enter)
        col_right.addWidget(self.chat_input)

        self.chat_save = QPushButton("Save Chat Logs", self)
        self.chat_save.clicked.connect(self.save_chat)
        col_right.addWidget(self.chat_save)

        self.user_map = PlotWidget()
        self.map_item = ScatterPlotItem(size=10)
        self.user_map.addItem(self.map_item)
        self.user_map.getPlotItem().hideAxis('left')
        self.user_map.getPlotItem().hideAxis('bottom')
        self.map_item.scene().sigMouseMoved.connect(self.map_hover)
        map_viewbox = self.map_item.getViewBox()
        map_viewbox.menu = None
        col_right.addWidget(self.user_map)

        self.user_map_info = QLineEdit("Hover over a user", self)
        self.user_map_info.setReadOnly(True)
        col_right.addWidget(self.user_map_info)

        self.setGeometry(300, 300, 800, 600)
        self.setWindowTitle('MineClass')

        self.stack.setCurrentIndex(0)
        self.activate_buttons(False)
        self.show()

        if is_newer_version_available():
            QMessageBox.about(
                self, "Newer Version Available",
                f'A newer version of this program is available <a href="{GITHUB_DOWNLOAD_URL}">here</a>.'
            )

        if not self.settings.value("HasRunFirstTime", False):
            self.show_connection_help()
            self.settings.setValue("HasRunFirstTime", True)

    def show_connection_help(self):
        QMessageBox.about(
            self, "Connection Help",
            '''Before using (or if Minecraft has been newly installed), go to Settings->Profile and disable "Require Encrypted Websockets"\n\n
Sometimes you'll need to attempt connecting twice (use the up arrow in the Minecraft terminal to access history'''
        )

    def save_chat(self):
        options = QFileDialog.Options()
        file_name, _ = QFileDialog.getSaveFileName(
            self,
            "Save Chat Logs",
            "",
            "Text Files (*.txt);;All Files (*)",
            options=options)
        if file_name:
            with open(file_name, "w") as f:
                f.write(self.chat_box.toPlainText())

    def chat_enter(self):
        server.send_chat(self.chat_input.text())
        self.update_chat_box("Teacher", self.chat_input.text(), "chat")
        self.chat_input.clear()

    def map_hover(self, pos):
        act_pos = self.map_item.mapFromScene(pos)
        points = self.map_item.pointsAt(act_pos)

        text = ""
        for p in points:
            text += f'{p.data()}: ({round(p.pos()[0])}, {round(p.pos()[1])}), '
        self.user_map_info.setText(text)

    def time_tick(self):
        self.server.get_users()

    def start_timer(self):
        self.time_tick()
        self.timer.start(10000)

    def stop_timer(self):
        self.timer.stop()

    def update_chat_box(self, sender, message, message_type, receiver=None):
        t = datetime.datetime.now().strftime("%H:%M:%S")
        if message_type == "chat":
            out = f'{t} <{sender}> {message}'
        elif message_type == "tell":
            out = f'{t} <{sender} whispers to {receiver}> {message}'
        self.chat_box.appendPlainText(out)

    def activate_buttons(self, activate):
        self.pause_button.setDisabled(not activate)

    def setup_toggle_button(self,
                            parent,
                            checked_action,
                            checked_text,
                            unchecked_action,
                            unchecked_text,
                            size=None):
        button = QPushButton(unchecked_text, self)
        button.resize(button.sizeHint() if size is None else size)
        button.setCheckable(True)
        parent.addWidget(button)

        def toggle_button_clicked(checked_status):
            if checked_status:
                checked_action()
                button.setText(checked_text)
            else:
                unchecked_action()
                button.setText(unchecked_text)

        button.toggled.connect(toggle_button_clicked)
        return button

    def get_students_from_grid(self):
        try:
            return [
                self.users_table.item(i, 0).text()
                for i in range(self.users_table.rowCount())
            ]
        except AttributeError:
            return []

    def edit_class(self):
        selection = self.classes_combo.currentText()
        if selection in ("Select class", "Add a class"):
            QMessageBox.about(self, "Error",
                              "Please select (or create) a class first")
            return

        current_list = self.get_students_from_grid()
        new_list, ok_pressed = QInputDialog().getMultiLineText(
            self,
            "Edit Class List",
            "Add or remove students from this class",
            text="\n".join(current_list))
        if ok_pressed:
            students = [i for i in new_list.split("\n")
                        if i]  # list comprehension to remove empty strings
            self.current_students = students
            self.settings.setValue(f'classes/{self.current_class}', students)
            self.load_users()

    def class_changed(self):
        selection = self.classes_combo.currentText()
        # if selection != "Select class":
        #     self.classes_combo.removeItem(self.classes_combo.findText("Select class"))
        if selection == "Add a class":
            new_class, ok_pressed = QInputDialog.getText(
                self, 'Class Name', 'Enter the Class Name or Code')
            if ok_pressed:
                classes = self.settings.value('class_names', [])
                if new_class in classes:
                    print('Class already exists; ignoring')
                else:
                    classes.append(new_class)
                    self.settings.setValue('class_names', classes)
                    self.classes_combo.addItem(new_class)
                self.classes_combo.setCurrentIndex(
                    self.classes_combo.findText(new_class))
        elif selection == "Select class":
            pass
        elif selection == "Delete a class":
            current_classes = self.settings.value('class_names', [])
            if current_classes:
                class_to_delete, ok_pressed = QInputDialog.getItem(
                    self, 'Delete Class', 'Select which class to delete',
                    current_classes, 0, False)
                if ok_pressed and class_to_delete:
                    current_classes.remove(class_to_delete)
                    self.settings.setValue('class_names', current_classes)
                    self.settings.remove(f'classes/{class_to_delete}')
                    self.classes_combo.removeItem(
                        self.classes_combo.findText(class_to_delete))
                    #TODO delete stdents from table
                    self.current_class = None
                    self.current_students = []
            else:
                QMessageBox.information(self, "No Classes!",
                                        "No Class to delete!")
            self.classes_combo.setCurrentIndex(0)
        else:
            self.current_class = selection
            self.current_students = self.settings.value(
                f'classes/{selection}', [])
            self.load_users()

    def load_users(self):
        if len(self.current_students) != self.users_table.rowCount():
            self.users_table.setRowCount(len(self.current_students))
        for i, user in enumerate(self.current_students):
            self.users_table.setItem(i, 0, QTableWidgetItem(user))
        self.users_table.sortItems(0, QtCore.Qt.AscendingOrder)
        self.users_table.sortItems(1, QtCore.Qt.DescendingOrder)

    def update_users_from_mc(self, users):
        table_user_count = self.users_table.rowCount()
        for i in range(table_user_count):
            current_table_user = self.users_table.item(i, 0).text()
            if current_table_user in users:
                tick = QTableWidgetItem("✓")
                tick.setTextAlignment(QtCore.Qt.AlignCenter)
                tick.setBackground(QColor(QtCore.Qt.green))
                self.users_table.setItem(i, 1, tick)
                users.remove(current_table_user)
            else:
                cross = QTableWidgetItem("✗")
                cross.setTextAlignment(QtCore.Qt.AlignCenter)
                cross.setBackground(QColor(QtCore.Qt.red))
                self.users_table.setItem(i, 1, cross)

        #handle users from server but not in table
        self.users_table.setRowCount(table_user_count + len(users))
        for i, user in enumerate(users):
            self.users_table.setItem(i + table_user_count, 0,
                                     QTableWidgetItem(user))

        self.users_table.sortItems(0, QtCore.Qt.AscendingOrder)
        self.users_table.sortItems(1, QtCore.Qt.DescendingOrder)
        self.users_table.resizeRowsToContents()

    def update_map(self, users):
        data = [
            {
                'pos': (int(u['position']['x']), int(u['position']['z'])),
                'data': u['name'],
                'brush': mkBrush(
                    'g'
                ),  #mkBrush("r" if u['name'] == self.server.self_name else "g"),
                'symbol': ("s" if u['name'] == self.server.self_name else "o"),
            } for u in users.values()
        ]
        self.map_item.setData(data)
コード例 #10
0
ファイル: qGraph.py プロジェクト: jonathanchenn/Osprey
class QGraph(QWidget):
    def __init__(self, config, parent=None, **kwargs):
        QWidget.__init__(self, parent)
        self.startTime = None
        self.numDataPoints = 0

        self.datasets = {}

        for display in config['displays']:
            self.datasets[display['field']] = self.createDatasetForDisplay(
                display)

        self.graph = PlotWidget(title=config['title'], labels=config['labels'])

        # Only add a legend to the graph if there is more than one dataset displayed on it
        if len(self.datasets) > 1:
            self.graph.addLegend()

        # Show grid lines
        self.graph.showGrid(x=True, y=True)

        for _, dataset in self.datasets.items():
            self.graph.addItem(dataset['plotData'])

        vbox = QVBoxLayout()
        vbox.addWidget(self.graph)
        self.setLayout(vbox)

    def createDatasetForDisplay(self, display):
        plotData = PlotDataItem(name=display['label'])

        if 'color' in display:
            plotData.setPen(mkPen({'color': display['color']}))

        return {
            'plotData': plotData,
            'points': numpy.zeros((constants.NUMPY_ARRAY_SIZE, 2)),
        }

    def updateDataset(self, dataset):
        time = self.getAxisTime(dataset)

        # Skip updating if no time is available
        if not time:
            return

        for field, _ in self.datasets.items():
            self.updatePoints(time, field, dataset)
            self.updateGraphs(field, dataset)

        self.numDataPoints += 1

    def updatePoints(self, time, field, dataset):
        for key, data in dataset.items():
            # Only plot float values
            if field == key and isinstance(data, float):
                self.datasets[field]['points'][self.numDataPoints] = (time,
                                                                      data)
                return

    def getAxisTime(self, dataset):
        # Use the first dataset as the start time
        if not self.startTime and dataset['delta']:
            self.startTime = dataset['delta']

        if dataset['delta']:
            return (dataset['delta'] - self.startTime)
        else:
            return None

    def updateGraphs(self, field, dataset):
        for data in dataset.items():
            if field in dataset:
                # We don't want to graph the empty values in the points array so only
                # give the plot data the points up to the current number of data points
                points = self.datasets[field]['points']
                self.datasets[field]['plotData'].setData(
                    points[0:self.numDataPoints])
コード例 #11
0
ファイル: __init__.py プロジェクト: LeCoz/Tiare
class Tiare(QtGui.QMainWindow):
    def __init__(self, *args):
        QtGui.QMainWindow.__init__(self, *args)
        self.statusBar().showMessage('Pret')
        self.th = 0
        self.widget = QtGui.QWidget(self)
        exitAction = QtGui.QAction(QtGui.QIcon('exit.png'), '&Quitter', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip("Ferme l'application")
        exitAction.triggered.connect(self.close)

        openAction = QtGui.QAction(QtGui.QIcon('open.png'), '&Charger', self)
        openAction.setShortcut('Ctrl+L')
        openAction.setStatusTip("Charge un fichier wav")
        openAction.triggered.connect(self.load)

        self.saveAction = QtGui.QAction(QtGui.QIcon('save.png'), '&Exporter', self)
        self.saveAction.setShortcut('Ctrl+S')
        self.saveAction.setStatusTip("Exporter en CSV")
        self.saveAction.triggered.connect(self.export)
        self.saveAction.setEnabled(False)
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&Fichier')
        fileMenu.addAction(openAction)
        fileMenu.addAction(self.saveAction)
        fileMenu.addAction(exitAction)

        self.th_slider = QtGui.QSlider(QtCore.Qt.Horizontal, self)
        self.th_slider.setValue(self.th)
        self.th_slider.valueChanged[int].connect(self.change_threshold)

        self.min_len = QtGui.QSlider(QtCore.Qt.Horizontal, self)
        self.min_len.setValue(10)
        self.min_len.setMinimum(1)
        self.min_len.setMaximum(100)
        self.min_len.valueChanged[int].connect(self.change_min_len)

        self.min_len_sil = QtGui.QSlider(QtCore.Qt.Horizontal, self)
        self.min_len_sil.setValue(10)
        self.min_len_sil.setMinimum(1)
        self.min_len_sil.setMaximum(100)
        self.min_len_sil.valueChanged[int].connect(self.change_min_len)


        # Make sizer and embed stuff
        self.sizer = QtGui.QVBoxLayout(self.widget)
        self.fig_signal = PlotWidget(self.widget, background="w")
        self.fig_signal.setLimits(xMin=0, yMin=-1, yMax=1, minXRange=1, maxXRange=30, minYRange=2, maxYRange=2)
        self.fig_energy = PlotWidget(self.widget, background="w")
        self.fig_energy.setXLink(self.fig_signal)
        self.fig_segments = PlotWidget(self.widget, background="w")
        self.fig_segments.setXLink(self.fig_signal)
        self.fig_segments.hideAxis('bottom')
        self.fig_segments.hideAxis('left')
        self.fig_segments.setLimits(yMin=-1, yMax=1, minYRange=2, maxYRange=2)

        self.sizer.addWidget(self.fig_signal, 5)
        self.sizer.addWidget(self.fig_energy, 5)
        self.sizer.addWidget(self.fig_segments, 3)
        self.sizer.addWidget(QtGui.QLabel('Seuil de segmentation'), 0)
        self.sizer.addWidget(self.th_slider, 0)
        self.min_seg_label = QtGui.QLabel('Longeur minimal de segment (%.3f s)' % (float(self.min_len.value())/100))
        self.sizer.addWidget(self.min_seg_label, 0)
        self.sizer.addWidget(self.min_len, 0)

        self.min_sil_label = QtGui.QLabel('Longeur minimal de silence (%.3f s)' % (float(self.min_len_sil.value())/100))
        self.sizer.addWidget(self.min_sil_label, 0)
        self.sizer.addWidget(self.min_len_sil, 0)

        # Apply sizers
        self.setCentralWidget(self.widget)

        # Finish
        self.resize(560, 420)
        self.setWindowTitle('Tiare')
        self.energy_tl, self.energy = [], []
        self.thline = None
        self.seg_up = None
        self.seg_down = None
        self.fig_energy_plot = None
        self.segments = []
        self.samples = []
        self.sr = 0
        self.filepath = None
        self.widget.hide()
        self.show()

    def change_threshold(self, value):
        value = float(value)/100
        if self.thline is not None :
            self.thline.setData([self.energy_tl[0], self.energy_tl[-1]], [value]*2)
            self.segments = map(lambda (x, y): (self.energy_tl[x],self.energy_tl[y]),
                                cut(self.energy, value, self.min_len.value(), self.min_len_sil.value()))
            x = [v for start, stop in self.segments for v in [start, start, stop, stop]]
            y = [v for _ in self.segments for v in [-0.85, 0.85, 0.85, -0.85]]
            self.seg_up.setData(x, y)
            self.seg_down.setData([self.energy_tl[0], self.energy_tl[-1]], [-0.85, -0.85])

    def change_min_len(self, value=0):
        self.min_seg_label.setText("Longeur minimale d'un segment (%.3f s)" % (float(self.min_len.value())/100))
        self.min_sil_label.setText("Longeur minimale d'un silence (%.3f s)" % (float(self.min_len_sil.value())/100))
        self.change_threshold(self.th_slider.value())

    def compute_energy(self, value=None):
        self.energy_tl, self.energy = energy(self.samples, self.sr)
        if self.fig_energy_plot is not None:
            self.fig_energy_plot.setData(self.energy_tl, self.energy)
            self.change_min_len()

    def export(self):
        fpath = QtGui.QFileDialog.getSaveFileName(self, "Sauvegader en CSV", self.filepath+".csv")
        if fpath:
            with open(fpath[0], "w") as f:

                for start, stop in self.segments:
                    f.write("Segments\t%s\t%s\n" % (datetime(day=1, month=1, year=1901, second=int(start),
                                                             microsecond=int(10e5*(start % 1)))
                                                    .strftime("%H:%M:%S.%f"),
                                                    datetime(day=1, month=1, year=1901, second=int(stop),
                                                             microsecond=int(10e5*(stop % 1)))
                                                    .strftime("%H:%M:%S.%f")))

    def load(self):
        fpath, _ = QtGui.QFileDialog.getOpenFileName(self, 'Choisir un fichier', '~/', filter="*.wav")
        self.widget.show()
        if fpath:
            self.filepath = fpath
            self.saveAction.setEnabled(True)

            self.samples, self.sr = load_sound(fpath)
            m = max(map(abs, self.samples))
            timeline = [float(t)/self.sr for t in range(len(self.samples))]
            self.fig_signal.setLimits(xMax=timeline[-1])

            self.compute_energy()

            self.fig_signal.getPlotItem().plot(timeline, map(lambda x: x/m, self.samples))
            self.fig_energy_plot = self.fig_energy.getPlotItem().plot(self.energy_tl, self.energy)
            self.thline = self.fig_energy.getPlotItem().plot([self.energy_tl[0], self.energy_tl[-1]],
                                                             [float(self.th_slider.value())/100]*2,
                                               pen=({'color': "k", "width": 1.5}))
            self.seg_up = self.fig_segments.getPlotItem().plot([self.energy_tl[0], self.energy_tl[-1]],
                                                               [-0.85, -0.85])

            self.seg_down = self.fig_segments.getPlotItem().plot([self.energy_tl[0], self.energy_tl[-1]],
                                                                 [-0.85, -0.85])
            self.segments = FillBetweenItem(self.seg_up, self.seg_down, 0.7)
            self.fig_segments.addItem(self.segments)
コード例 #12
0
ファイル: GUI.py プロジェクト: DabenW/AutoCoach
class Ui_MainWindow(object):
    def __init__(self):

        self._coin_gold0 = QtGui.QPixmap('icons/events/coin_gold0.png')
        self._coin_gold1 = QtGui.QPixmap('icons/events/coin_gold1.png')
        self._coin_gold2 = QtGui.QPixmap('icons/events/coin_gold2.png')
        self._gold_coin = QtGui.QPixmap('icons/events/coin_gold0.png')
        self._grey_coin = QtGui.QPixmap('icons/events/coin_gold1.png')

        self.grey_bar = QtGui.QPixmap('icons/bars/grey_bar.png')
        self.top_bar = QtGui.QPixmap('icons/bars/top_bar.png')
        self.medium_bar = QtGui.QPixmap('icons/bars/medium_bar.png')
        self.bottom_bar = QtGui.QPixmap('icons/bars/bottom_bar.png')

        self.green_glow = pg.QtGui.QGraphicsPixmapItem(
            pg.QtGui.QPixmap('icons/glow/Green-Glow.png'))
        self.orange_glow = pg.QtGui.QGraphicsPixmapItem(
            pg.QtGui.QPixmap('icons/glow/Orange-Glow.png'))
        self.yellow_glow = pg.QtGui.QGraphicsPixmapItem(
            pg.QtGui.QPixmap('icons/glow/Yellow-Glow.png'))

        self.brake_icon = QtGui.QIcon('icons/events/Brake.svg')
        self.acc_icon = QtGui.QIcon('icons/events/Accelerate.svg')
        self.turn_icon = QtGui.QIcon('icons/events/Turn.svg')
        self.swerve_icon = QtGui.QIcon('icons/events/Swerve.svg')
        pass

    windowMoved = QtCore.pyqtSignal(QtCore.QPoint)

    def update2(self):
        data3 = self.data3
        ptr3 = self.ptr3
        data3[ptr3] = np.random.normal()

        ptr3 += 1
        if ptr3 >= data3.shape[0]:
            tmp = data3
            data3 = np.empty(data3.shape[0] * 2)
            data3[:tmp.shape[0]] = tmp
        self.pen1.setData(data3[:ptr3])
        self.data3 = data3
        if (ptr3 > 100):
            self.pen1.setPen(pg.mkPen('r', width=3))
        self.pen1.setPos(-ptr3, 0)
        self.ptr3 = ptr3

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(750, 500)
        MainWindow.setTabShape(QtWidgets.QTabWidget.Rounded)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                           QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.centralwidget.sizePolicy().hasHeightForWidth())
        self.centralwidget.setSizePolicy(sizePolicy)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setContentsMargins(5, 10, 5, 0)
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.bar = QtWidgets.QWidget(self.centralwidget)
        self.bar.setMaximumSize(QtCore.QSize(16777215, 30))
        self.bar.setObjectName("bar")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.bar)
        self.horizontalLayout.setContentsMargins(-1, 5, 11, 5)
        self.horizontalLayout.setSpacing(9)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.exit = QtWidgets.QPushButton(self.bar)
        self.exit.setMaximumSize(QtCore.QSize(30, 20))
        self.exit.setText("")
        self.exit.setObjectName("close")
        self.horizontalLayout.addWidget(self.exit)
        self.visit = QtWidgets.QPushButton(self.bar)
        self.visit.setMaximumSize(QtCore.QSize(30, 20))
        self.visit.setText("")
        self.visit.setObjectName("visit")
        self.horizontalLayout.addWidget(self.visit)
        self.mini = QtWidgets.QPushButton(self.bar)
        self.mini.setMaximumSize(QtCore.QSize(30, 20))
        self.mini.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.mini.setText("")
        self.mini.setAutoDefault(False)
        self.mini.setDefault(False)
        self.mini.setFlat(False)
        self.mini.setObjectName("mini")
        self.horizontalLayout.addWidget(self.mini)
        spacerItem = QtWidgets.QSpacerItem(40, 15,
                                           QtWidgets.QSizePolicy.Expanding,
                                           QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        self.next_page = QtWidgets.QPushButton(self.bar)
        self.next_page.setMaximumSize(QtCore.QSize(85, 30))
        self.next_page.setObjectName("next_page")
        self.horizontalLayout.addWidget(self.next_page)
        self.verticalLayout.addWidget(self.bar)
        self.Menu = QtWidgets.QGridLayout()
        self.Menu.setObjectName("Menu")
        self.down = QtWidgets.QWidget(self.centralwidget)
        self.down.setMinimumSize(QtCore.QSize(0, 130))
        self.down.setMaximumSize(QtCore.QSize(16777215, 16777215))
        self.down.setObjectName("down")
        self.gridLayout_down = QtWidgets.QGridLayout(self.down)
        self.gridLayout_down.setHorizontalSpacing(5)
        self.gridLayout_down.setObjectName("gridLayout_down")
        # pg.setConfigOption('background', '#17191A')
        self.widget = PlotWidget(self.down)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                           QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.widget.sizePolicy().hasHeightForWidth())
        self.widget.setSizePolicy(sizePolicy)
        self.widget.setMinimumSize(QtCore.QSize(0, 0))
        self.widget.setMaximumSize(QtCore.QSize(300, 120))
        self.widget.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.widget.setObjectName("widget")
        self.gridLayout_down.addWidget(self.widget, 0, 0, 1, 1)

        self.current_score = QtWidgets.QLabel(self.down)
        # sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
        # sizePolicy.setHorizontalStretch(0)
        # sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.current_score.sizePolicy().hasHeightForWidth())
        self.current_score.setSizePolicy(sizePolicy)
        self.current_score.setMinimumSize(QtCore.QSize(20, 60))
        self.current_score.setMaximumSize(QtCore.QSize(300, 120))
        font = QtGui.QFont()
        font.setFamily("Brush Script Std")
        font.setPointSize(50)
        font.setBold(True)
        font.setWeight(75)
        self.current_score.setFont(font)
        self.current_score.setAlignment(QtCore.Qt.AlignCenter)
        self.current_score.setObjectName("CurrentScore")
        self.gridLayout_down.addWidget(self.current_score, 0, 1, 1, 1)

        self.total_score = QtWidgets.QPushButton()
        self.total_score.setWindowFlag(QtCore.Qt.FramelessWindowHint)
        self.total_score.setMinimumSize(QtCore.QSize(0, 0))
        self.total_score.setMaximumSize(QtCore.QSize(250, 120))
        self.total_score.setFlat(True)
        font = QtGui.QFont()
        font.setPointSize(15)
        font.setKerning(True)
        font.setBold(True)
        font.setFamily("Brush Script Std")
        self.total_score.setStyleSheet(
            'QPushButton {background-color: #17191A; color: white;}')
        self.total_score.setFont(font)
        self.total_score.setLayoutDirection(QtCore.Qt.RightToLeft)
        # self.TotalScore.setAlignment(QtCore.Qt.AlignCenter)
        self.total_score.setObjectName("TotalScore")
        self.gridLayout_down.addWidget(self.total_score, 0, 2, 1, 1)
        self.Menu.addWidget(self.down, 4, 0, 1, 1)
        self.line = QtWidgets.QFrame(self.centralwidget)
        self.line.setFrameShadow(QtWidgets.QFrame.Plain)
        self.line.setLineWidth(10)
        self.line.setFrameShape(QtWidgets.QFrame.HLine)
        self.line.setObjectName("line")
        self.Menu.addWidget(self.line, 1, 0, 1, 1)
        self.up = QtWidgets.QWidget(self.centralwidget)
        self.up.setMinimumSize(QtCore.QSize(0, 0))
        self.up.setMaximumSize(QtCore.QSize(16777215, 16777215))
        self.up.setObjectName("up")
        self.gridLayout_up = QtWidgets.QGridLayout(self.up)
        self.gridLayout_up.setContentsMargins(-1, 0, -1, 0)
        self.gridLayout_up.setHorizontalSpacing(0)
        self.gridLayout_up.setVerticalSpacing(0)
        self.gridLayout_up.setSpacing(0)
        self.gridLayout_up.setObjectName("gridLayout_up")

        self.turn_bar = QtWidgets.QWidget(self.up)
        self.turn_bar.setMaximumSize(QtCore.QSize(80, 220))
        self.turn_bar.setObjectName("Turn_bar")
        self.verticalLayout_turn = QtWidgets.QVBoxLayout(self.turn_bar)
        self.verticalLayout_turn.setContentsMargins(15, 0, 15, 0)
        self.verticalLayout_turn.setSpacing(0)
        self.verticalLayout_turn.setObjectName("verticalLayout_turn")
        self.turn_bar1 = QtWidgets.QLabel(self.turn_bar)
        self.turn_bar1.setText("")
        self.turn_bar1.setObjectName("turn_bar1")
        self.verticalLayout_turn.addWidget(self.turn_bar1)
        self.turn_bar2 = QtWidgets.QLabel(self.turn_bar)
        self.turn_bar2.setText("")
        self.turn_bar2.setObjectName("turn_bar2")
        self.verticalLayout_turn.addWidget(self.turn_bar2)
        self.turn_bar3 = QtWidgets.QLabel(self.turn_bar)
        self.turn_bar3.setText("")
        self.turn_bar3.setObjectName("turn_bar3")
        self.verticalLayout_turn.addWidget(self.turn_bar3)
        self.gridLayout_up.addWidget(self.turn_bar, 0, 5, 1, 1)

        self.turn_level = QtWidgets.QWidget(self.up)
        self.turn_level.setMaximumSize(QtCore.QSize(80, 35))
        self.turn_level.setObjectName("Turn_level")
        self.gridLayout_up.addWidget(self.turn_level, 1, 5, 1, 1)

        self.acc_bar = QtWidgets.QWidget(self.up)
        self.acc_bar.setMaximumSize(QtCore.QSize(80, 220))
        self.acc_bar.setObjectName("Acc_bar")
        self.verticalLayout_acc = QtWidgets.QVBoxLayout(self.acc_bar)
        self.verticalLayout_acc.setContentsMargins(15, 0, 15, 0)
        self.verticalLayout_acc.setSpacing(0)
        self.verticalLayout_acc.setObjectName("verticalLayout_acc")
        self.acc_bar1 = QtWidgets.QLabel(self.acc_bar)
        self.acc_bar1.setText("")
        self.acc_bar1.setObjectName("acc_bar1")
        self.verticalLayout_acc.addWidget(self.acc_bar1)
        self.acc_bar2 = QtWidgets.QLabel(self.acc_bar)
        self.acc_bar2.setText("")
        self.acc_bar2.setObjectName("acc_bar2")
        self.verticalLayout_acc.addWidget(self.acc_bar2)
        self.acc_bar3 = QtWidgets.QLabel(self.acc_bar)
        self.acc_bar3.setText("")
        self.acc_bar3.setObjectName("acc_bar3")
        self.verticalLayout_acc.addWidget(self.acc_bar3)
        self.gridLayout_up.addWidget(self.acc_bar, 0, 0, 1, 1)

        spacer1 = QtWidgets.QSpacerItem(15, 20, QtWidgets.QSizePolicy.Fixed,
                                        QtWidgets.QSizePolicy.Minimum)
        self.gridLayout_up.addItem(spacer1, 0, 2, 1, 1)
        pg.setConfigOption('background', '#FCFCFC')

        self.backCircle = PlotWidget(self.up)
        self.backCircle.setMinimumSize(QtCore.QSize(50, 50))
        self.backCircle.setMaximumSize(QtCore.QSize(300, 320))
        self.backCircle.setObjectName("backCircle")
        self.backCircle.getPlotItem().hideAxis('bottom')
        self.backCircle.getPlotItem().hideAxis('left')
        self.backCircleLayout = QtWidgets.QGridLayout(self.backCircle)
        self.backCircleLayout.setContentsMargins(60, 50, 60, 50)
        self.backCircleLayout.setObjectName("backCircleLayout")

        self.feedback = QtWidgets.QToolButton(self.backCircle)
        self.feedback.setEnabled(False)
        self.feedback.setMinimumSize(QtCore.QSize(50, 50))
        self.feedback.setMaximumSize(QtCore.QSize(320, 320))
        self.feedback.setFocusPolicy(QtCore.Qt.TabFocus)
        self.feedback.setText("")
        self.feedback.setObjectName("feedback")

        self.backCircleLayout.addWidget(self.feedback, 0, 0, 1, 1)
        self.gridLayout_up.addWidget(self.backCircle, 0, 3, 2, 1)
        self.brake_bar = QtWidgets.QWidget(self.up)
        self.brake_bar.setMaximumSize(QtCore.QSize(80, 220))
        self.brake_bar.setObjectName("Brake_bar")
        self.verticalLayout_brake = QtWidgets.QVBoxLayout(self.brake_bar)
        self.verticalLayout_brake.setContentsMargins(15, 0, 15, 0)
        self.verticalLayout_brake.setSpacing(0)
        self.verticalLayout_brake.setObjectName("verticalLayout_brake")
        self.brake_bar1 = QtWidgets.QLabel(self.brake_bar)
        self.brake_bar1.setText("")
        self.brake_bar1.setObjectName("brake_bar1")
        self.verticalLayout_brake.addWidget(self.brake_bar1)
        self.brake_bar2 = QtWidgets.QLabel(self.brake_bar)
        self.brake_bar2.setText("")
        self.brake_bar2.setObjectName("brake_bar2")
        self.verticalLayout_brake.addWidget(self.brake_bar2)
        self.brake_bar3 = QtWidgets.QLabel(self.brake_bar)
        self.brake_bar3.setText("")
        self.brake_bar3.setObjectName("brake_bar3")
        self.verticalLayout_brake.addWidget(self.brake_bar3)
        self.gridLayout_up.addWidget(self.brake_bar, 0, 1, 1, 1)

        self.Swerve_level = QtWidgets.QWidget(self.up)
        self.Swerve_level.setMaximumSize(QtCore.QSize(80, 35))
        self.Swerve_level.setObjectName("Swerve_level")

        self.gridLayout_up.addWidget(self.Swerve_level, 1, 6, 1, 1)
        self.Swerve_bar = QtWidgets.QWidget(self.up)
        self.Swerve_bar.setMaximumSize(QtCore.QSize(80, 220))
        self.Swerve_bar.setObjectName("Swerve_bar")
        self.verticalLayout_swerve = QtWidgets.QVBoxLayout(self.Swerve_bar)
        self.verticalLayout_swerve.setContentsMargins(15, 0, 15, 0)
        self.verticalLayout_swerve.setSpacing(0)
        self.verticalLayout_swerve.setObjectName("verticalLayout_swerve")
        self.swerve_bar1 = QtWidgets.QLabel(self.Swerve_bar)
        self.swerve_bar1.setText("")
        self.swerve_bar1.setObjectName("swerve_bar1")
        self.verticalLayout_swerve.addWidget(self.swerve_bar1)
        self.swerve_bar2 = QtWidgets.QLabel(self.Swerve_bar)
        self.swerve_bar2.setText("")
        self.swerve_bar2.setObjectName("swerve_bar2")
        self.verticalLayout_swerve.addWidget(self.swerve_bar2)
        self.swerve_bar3 = QtWidgets.QLabel(self.Swerve_bar)
        self.swerve_bar3.setText("")
        self.swerve_bar3.setObjectName("swerve_bar3")
        self.verticalLayout_swerve.addWidget(self.swerve_bar3)
        self.gridLayout_up.addWidget(self.Swerve_bar, 0, 6, 1, 1)

        self.acc_level = PlotWidget(self.up)
        self.acc_level.setMaximumSize(QtCore.QSize(80, 35))
        self.acc_level.setObjectName("Acc_level")
        self.acc_level.setFocusPolicy(QtCore.Qt.TabFocus)
        self.acc_level.getPlotItem().hideAxis('bottom')
        self.acc_level.getPlotItem().hideAxis('left')

        self.gridLayout_up.addWidget(self.acc_level, 1, 0, 1, 1)
        self.brake_level = QtWidgets.QWidget(self.up)
        self.brake_level.setMaximumSize(QtCore.QSize(80, 35))
        self.brake_level.setObjectName("Brake_level")
        self.gridLayout_up.addWidget(self.brake_level, 1, 1, 1, 1)
        spacer2 = QtWidgets.QSpacerItem(15, 20, QtWidgets.QSizePolicy.Fixed,
                                        QtWidgets.QSizePolicy.Minimum)
        self.gridLayout_up.addItem(spacer2, 0, 4, 1, 1)
        self.Menu.addWidget(self.up, 0, 0, 1, 1)
        self.verticalLayout.addLayout(self.Menu)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 750, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        # these are three control buttons
        self.exit.setFixedSize(15, 15)
        self.visit.setFixedSize(15, 15)
        self.mini.setFixedSize(15, 15)
        self.exit.setStyleSheet(
            '''QPushButton{background:#F76677;border-radius:5px;}QPushButton:hover{background:red;}'''
        )
        self.next_page.setFixedSize(80, 20)
        # self.visit.setStyleSheet('''QPushButton{background:#F7D674;border-radius:5px;}QPushButton:hover{background:yellow;}''')
        # self.mini.setStyleSheet('''QPushButton{background:#6DDF6D;border-radius:5px;}QPushButton:hover{background:green;}''')

        # beautify window
        self.setWindowFlag(QtCore.Qt.FramelessWindowHint)  # hide the boarder
        self.setWindowOpacity(0.98)
        self.setAttribute(
            QtCore.Qt.WA_TranslucentBackground)  # set transparent window
        self.exit.clicked.connect(self.close)  # close window
        self.mini.clicked.connect(self.showMinimized)  # minimum window
        self.windowMoved.connect(self.move)  # move window

        self.acc_pic_coin = QtWidgets.QLabel(self.acc_level)
        self.acc_pic_coin.setMargin(5)
        self.acc_pic_coin.setPixmap(self._gold_coin)
        self.acc_pic_coin.setScaledContents(True)
        self.acc_pic_coin.setMaximumSize(QtCore.QSize(80, 31))

        self.brake_pic_coin = QtWidgets.QLabel(self.brake_level)
        self.brake_pic_coin.setMargin(5)
        self.brake_pic_coin.setPixmap(self._grey_coin)
        self.brake_pic_coin.setScaledContents(True)
        self.brake_pic_coin.setMaximumSize(QtCore.QSize(80, 31))

        self.turn_pic_coin = QtWidgets.QLabel(self.turn_level)
        self.turn_pic_coin.setMargin(5)
        self.turn_pic_coin.setPixmap(self._grey_coin)
        self.turn_pic_coin.setScaledContents(True)
        self.turn_pic_coin.setMaximumSize(QtCore.QSize(80, 31))

        self.swerve_pic_coin = QtWidgets.QLabel(self.Swerve_level)
        self.swerve_pic_coin.setMargin(5)
        self.swerve_pic_coin.setPixmap(self._gold_coin)
        self.swerve_pic_coin.setScaledContents(True)
        self.swerve_pic_coin.setMaximumSize(QtCore.QSize(80, 31))

        # # self.acc_bar_top = QtWidgets.QLabel(self.acc_bar1)
        # self.acc_bar1.setPixmap(self.acc_bar1)
        # self.acc_bar1.setScaledContents(True)
        # self.acc_bar1.setMaximumSize(QtCore.QSize(50, 67))
        #
        #
        # self.acc_bar2 = QtWidgets.QLabel(self.acc_bar2)
        # self.acc_bar2.setPixmap(self.acc_bar2)
        # self.acc_bar2.setScaledContents(True)
        # self.acc_bar2.setMaximumSize(QtCore.QSize(50, 67))
        #
        #
        # self.acc_bar3 = QtWidgets.QLabel(self.acc_bar3)
        # self.acc_bar3.setPixmap(self.acc_bar3)
        # self.acc_bar3.setScaledContents(True)
        # self.acc_bar3.setMaximumSize(QtCore.QSize(50, 67))

        # draw graph of lines--should be deleted later

        self.widget.setDownsampling(mode='peak')
        self.widget.setClipToView(True)
        self.widget.setXRange(0, 100)
        self.widget.setLimits(xMax=0)
        self.pen1 = self.widget.plot()
        self.pen1.setPen(pg.mkPen('y', width=3))
        self.data3 = np.empty(10)
        self.ptr3 = 0

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

    def mousePressEvent(self, event):
        if event.button() == QtCore.Qt.LeftButton:
            self.mPos = event.pos()
        event.accept()

    def mouseReleaseEvent(self, event):
        self.mPos = None
        event.accept()

    def mouseMoveEvent(self, event):
        if event.buttons() == QtCore.Qt.LeftButton and self.mPos:
            self.windowMoved.emit(self.mapToGlobal(event.pos() - self.mPos))
        event.accept()

    # set current score and update
    def setCurrentScore(self, score):
        self.current_score.setText(str(score))

    # set Total score for trip
    def setTotalScore(self, score):
        self.total_score.setText(str(score) + ' points')

    def setFeedBack(self, level: int, type: str):
        if level == 0:
            self.backCircle.clear()
            self.backCircle.addItem(self.green_glow)
        elif level == 1:
            self.backCircle.clear()
            self.backCircle.addItem(self.yellow_glow)
        elif level == 2:
            self.backCircle.clear()
            self.backCircle.addItem(self.orange_glow)

        if type == 'acc':
            self.feedback.setIcon(self.acc_icon)
            self.feedback.setIconSize(QtCore.QSize(150, 150))
        elif type == 'brake':
            self.feedback.setIcon(self.brake_icon)
            self.feedback.setIconSize(QtCore.QSize(150, 150))
        elif type == 'turn':
            self.feedback.setIcon(self.turn_icon)
            self.feedback.setIconSize(QtCore.QSize(150, 150))
        elif type == 'swerve':
            self.feedback.setIcon(self.swerve_icon)
            self.feedback.setIconSize(QtCore.QSize(150, 150))

    def change_icons(self, level: int, type: str):
        if type == 'acc':
            self.change_acc_icon(level)
        elif type == 'brake':
            self.change_brake_icon(level)
        elif type == 'turn':
            self.change_turn_icon(level)
        elif type == 'swerve':
            self.change_swerve_icon(level)

    def change_acc_icon(self, level: int):
        if level == 0:
            self.acc_pic_coin.setPixmap(self._coin_gold0)
        elif level == 1:
            self.acc_pic_coin.setPixmap(self._coin_gold1)
        elif level == 2:
            self.acc_pic_coin.setPixmap(self._coin_gold2)

    def change_brake_icon(self, level: int):
        if level == 0:
            self.brake_pic_coin.setPixmap(self._coin_gold0)
        elif level == 1:
            self.brake_pic_coin.setPixmap(self._coin_gold1)
        elif level == 2:
            self.brake_pic_coin.setPixmap(self._coin_gold2)

    def change_turn_icon(self, level: int):
        if level == 0:
            self.turn_pic_coin.setPixmap(self._coin_gold0)
        elif level == 1:
            self.turn_pic_coin.setPixmap(self._coin_gold1)
        elif level == 2:
            self.turn_pic_coin.setPixmap(self._coin_gold2)

    def change_swerve_icon(self, level: int):
        if level == 0:
            self.swerve_pic_coin.setPixmap(self._coin_gold0)
        elif level == 1:
            self.swerve_pic_coin.setPixmap(self._coin_gold1)
        elif level == 2:
            self.swerve_pic_coin.setPixmap(self._coin_gold2)

    def setBar(self, level: str, type: str):
        if type == 'acc':
            self.change_acc_bar(level)
        elif type == 'brake':
            self.change_brake_bar(level)
        elif type == 'turn':
            self.change_turn_bar(level)
        elif type == 'swerve':
            self.change_swerve_bar(level)

    def change_acc_bar(self, level):
        if level == 'safe':
            self.acc_bar1.setPixmap(self.grey_bar)
            self.acc_bar2.setPixmap(self.grey_bar)
            self.acc_bar3.setPixmap(self.bottom_bar)
        elif level == 'mediumrisk':
            self.acc_bar1.setPixmap(self.grey_bar)
            self.acc_bar2.setPixmap(self.medium_bar)
            self.acc_bar3.setPixmap(self.bottom_bar)
        elif level == 'highrisk':
            self.acc_bar1.setPixmap(self.top_bar)
            self.acc_bar2.setPixmap(self.medium_bar)
            self.acc_bar3.setPixmap(self.bottom_bar)
        self.acc_bar1.setScaledContents(True)
        self.acc_bar2.setScaledContents(True)
        self.acc_bar3.setScaledContents(True)
        self.acc_bar1.setMaximumSize(QtCore.QSize(50, 67))
        self.acc_bar2.setMaximumSize(QtCore.QSize(50, 67))
        self.acc_bar3.setMaximumSize(QtCore.QSize(50, 67))

    def change_turn_bar(self, level):
        if level == 'safe':
            self.turn_bar1.setPixmap(self.grey_bar)
            self.turn_bar2.setPixmap(self.grey_bar)
            self.turn_bar3.setPixmap(self.bottom_bar)
        elif level == 'mediumrisk':
            self.turn_bar1.setPixmap(self.grey_bar)
            self.turn_bar2.setPixmap(self.medium_bar)
            self.turn_bar3.setPixmap(self.bottom_bar)
        elif level == 'highrisk':
            self.turn_bar1.setPixmap(self.top_bar)
            self.turn_bar2.setPixmap(self.medium_bar)
            self.turn_bar3.setPixmap(self.bottom_bar)
        self.turn_bar1.setScaledContents(True)
        self.turn_bar2.setScaledContents(True)
        self.turn_bar3.setScaledContents(True)
        self.turn_bar1.setMaximumSize(QtCore.QSize(50, 67))
        self.turn_bar2.setMaximumSize(QtCore.QSize(50, 67))
        self.turn_bar3.setMaximumSize(QtCore.QSize(50, 67))

    def change_swerve_bar(self, level):
        if level == 'safe':
            self.swerve_bar1.setPixmap(self.grey_bar)
            self.swerve_bar2.setPixmap(self.grey_bar)
            self.swerve_bar3.setPixmap(self.bottom_bar)
        elif level == 'mediumrisk':
            self.swerve_bar1.setPixmap(self.grey_bar)
            self.swerve_bar2.setPixmap(self.medium_bar)
            self.swerve_bar3.setPixmap(self.bottom_bar)
        elif level == 'highrisk':
            self.swerve_bar1.setPixmap(self.top_bar)
            self.swerve_bar2.setPixmap(self.medium_bar)
            self.swerve_bar3.setPixmap(self.bottom_bar)
        self.swerve_bar1.setScaledContents(True)
        self.swerve_bar2.setScaledContents(True)
        self.swerve_bar3.setScaledContents(True)
        self.swerve_bar1.setMaximumSize(QtCore.QSize(50, 67))
        self.swerve_bar2.setMaximumSize(QtCore.QSize(50, 67))
        self.swerve_bar3.setMaximumSize(QtCore.QSize(50, 67))

    def change_brake_bar(
        self,
        level,
    ):
        if level == 'safe':
            self.brake_bar1.setPixmap(self.grey_bar)
            self.brake_bar2.setPixmap(self.grey_bar)
            self.brake_bar3.setPixmap(self.bottom_bar)
        elif level == 'mediumrisk':
            self.brake_bar1.setPixmap(self.grey_bar)
            self.brake_bar2.setPixmap(self.medium_bar)
            self.brake_bar3.setPixmap(self.bottom_bar)
        elif level == 'highrisk':
            self.brake_bar1.setPixmap(self.top_bar)
            self.brake_bar2.setPixmap(self.medium_bar)
            self.brake_bar3.setPixmap(self.bottom_bar)
        self.brake_bar1.setScaledContents(True)
        self.brake_bar2.setScaledContents(True)
        self.brake_bar3.setScaledContents(True)
        self.brake_bar1.setMaximumSize(QtCore.QSize(50, 67))
        self.brake_bar2.setMaximumSize(QtCore.QSize(50, 67))
        self.brake_bar3.setMaximumSize(QtCore.QSize(50, 67))

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.current_score.setText(_translate("MainWindow", "86"))
        self.total_score.setText(_translate("MainWindow", "1240 points"))
        self.next_page.setText(_translate("MainWindow", "Next Page>>"))
コード例 #13
0
ファイル: eventWindows.py プロジェクト: Ilmosal/NorLyst
class SpectrogramWindow(QWidget):
    """
    This is the class for the spectrogram window
    """
    def __init__(self, station_list):
        super(QWidget, self).__init__()
        self.layout = QGridLayout(self)
        self.station_list = station_list
        self.hidden = False

        self.spectrogram_1 = PlotWidget(self)
        self.spectrogram_1.setFixedWidth(400)
        self.spectrogram_1.setFixedHeight(550)
        self.spectrogram_2 = PlotWidget(self)
        self.spectrogram_2.setFixedWidth(400)

        self.station_box_1 = QComboBox(self)
        self.station_box_2 = QComboBox(self)

        self.waiting_traces = [None, None]
        self.waiting_p_picks = [None, None]
        self.filter_stats = FilterStats(True)

        self.spectrogram_threads = [None, None]
        self.spectrogram_threads[0] = SpectrogramCalculatorThread(
            self.filter_stats, 0)
        self.spectrogram_threads[0].signal.connect(self.plotSpectrogram)
        self.spectrogram_threads[1] = SpectrogramCalculatorThread(
            self.filter_stats, 1)
        self.spectrogram_threads[1].signal.connect(self.plotSpectrogram)

        self.filter_widget = FilterWidget(self, self.filter_stats)

        self.layout.addWidget(self.spectrogram_1, 0, 0, 1, 2)
        self.layout.addWidget(self.spectrogram_2, 0, 2, 1, 2)
        self.layout.addWidget(self.station_box_1, 1, 0)
        self.layout.addWidget(self.station_box_2, 1, 2)
        self.layout.addWidget(self.filter_widget, 2, 0)

        self.station_box_1.activated.connect(self.replotSpectrogram1)
        self.station_box_2.activated.connect(self.replotSpectrogram2)
        self.setStationsFromNewEvent()

    def closeEvent(self, event):
        """
        This function will be called when the spectrogramWindow Closes
        """
        self.hidden = True

    def replotSpectrogram1(self):
        """
        This function is to be used only by station_box_1
        """
        self.getTraceForSpectrogramThread(0)

    def replotSpectrogram2(self):
        """
        This function is to be used only by station_box_2
        """
        self.getTraceForSpectrogramThread(1)

    def getTraceForSpectrogramThread(self, spectrogram_id):
        """
        Fetch correct trace for the spectrogram_thread. Choose this from the value from station_box_1 or station_box_2
        """
        station_name = None
        if spectrogram_id == 0:
            station_name = self.station_box_1.currentText()
        elif spectrogram_id == 1:
            station_name = self.station_box_2.currentText()

        trace, p_pick = self.station_list.getCurrentTraceAndPPickForStation(
            station_name)

        if trace is None:
            return

        self.calculateSpectrogram(trace, p_pick, spectrogram_id)

    def setStationsFromNewEvent(self):
        """
        Set the focused event to spectrogram window
        """
        stations = [x[0] for x in self.station_list.getOrderedStationList()]

        if len(stations) < 2:
            return

        self.station_box_1.clear()
        self.station_box_2.clear()

        for stat in stations:
            self.station_box_1.addItem(stat)
            self.station_box_2.addItem(stat)

        self.station_box_1.setCurrentIndex(0)
        self.station_box_2.setCurrentIndex(1)

        self.getTraceForSpectrogramThread(0)
        self.getTraceForSpectrogramThread(1)

    def filterChange(self):
        """
        Function that is called when the filters have been changed
        """
        self.getTraceForSpectrogramThread(0)
        self.getTraceForSpectrogramThread(1)

    def calculateSpectrogram(self, waveform_trace, p_pick, spectrogram_id):
        """
        Function for calculating a spectrogram
        """
        if self.spectrogram_threads[spectrogram_id].running:
            self.waiting_traces[spectrogram_id] = waveform_trace
            self.waiting_p_picks[spectrogram_id] = p_pick
            self.spectrogram_threads[spectrogram_id].interrupt = True
        else:
            self.spectrogram_threads[
                spectrogram_id].waveform_trace = waveform_trace
            self.spectrogram_threads[spectrogram_id].p_pick = p_pick
            self.spectrogram_threads[spectrogram_id].running = True
            self.spectrogram_threads[spectrogram_id].start()

    def plotSpectrogram(self, return_values):
        """
        Function for plotting a spectrogram
        """
        spectrogram_id, spectrogram, sample_frequencies, sample_times = return_values
        print("Window {0} done".format(spectrogram_id))

        self.spectrogram_threads[spectrogram_id].running = False
        self.spectrogram_threads[spectrogram_id].interrupt = False

        if self.waiting_traces[spectrogram_id] is not None:
            self.calculateSpectrogram(self.waiting_traces[spectrogram_id],
                                      self.waiting_p_picks[spectrogram_id],
                                      spectrogram_id)
            self.waiting_traces[spectrogram_id] = None
            self.waiting_p_picks[spectrogram_id] = None

        if spectrogram is None:
            return

        if spectrogram_id == 0:
            self.spectrogram_1.clear()
            self.spectrogram_1.addItem(spectrogram)
        elif spectrogram_id == 1:
            self.spectrogram_2.clear()
            self.spectrogram_2.addItem(spectrogram)
コード例 #14
0
class widget_mfi_lin_plot(QWidget):

    #-----------------------------------------------------------------------
    # DEFINE THE INITIALIZATION FUNCTION.
    #-----------------------------------------------------------------------

    def __init__(self, core):

        # Inherit all attributes of an instance of "QWidget".

        super(widget_mfi_lin_plot, self).__init__()

        # Store the Janus core.

        self.core = core

        # Prepare to respond to signals received from the core.

        self.connect(self.core, SIGNAL('janus_rset'), self.resp_rset)
        self.connect(self.core, SIGNAL('janus_chng_mfi'), self.resp_chng_mfi)

        # Initialize this widget's instance of "PlotWidget", which will
        # contain the plot of MFI magnetic field data.

        # Note.  The "QGridLayout" object given to this widget as its
        #        layout is essentially a dummy.  I could have just had
        #        this class inherit "PlotWidget", but I think that this
        #        gives me a bit more control (and a similar structure
        #        "janus_widget_fc_cup").

        self.setLayout(QGridLayout())

        self.plt = PlotWidget()
        self.layout().addWidget(self.plt)

        self.layout().setContentsMargins(0, 0, 0, 0)

        # Extract the individual elements of the "PlotWidget" object
        # (e.g., it's axes) for more convenient access later.

        self.vbx = self.plt.getViewBox()

        self.axs_x = self.plt.getAxis('bottom')
        self.axs_y = self.plt.getAxis('left')

        self.ptm = self.plt.getPlotItem()

        # Initialize and store the pens and fonts.

        self.pen_vbx = mkPen(color='k')
        self.pen_crv_m = mkPen(color='k')
        self.pen_crv_n = mkPen(color='k')
        self.pen_crv_x = mkPen(color='r')
        self.pen_crv_y = mkPen(color='g')
        self.pen_crv_z = mkPen(color='b')

        self.fnt = self.core.app.font()

        # Configure the plot: disable automatic adjustments and
        # adjustments made by the user, change the background and
        # foreground colors, enable grid lines for both axes, label the
        # axes, adjust the tick font size, adjust the "AxisItem" sizes,
        # and add a margin around the entire plot.

        self.plt.disableAutoRange()
        self.plt.setMouseEnabled(False, False)
        self.plt.setMenuEnabled(False)
        self.plt.hideButtons()

        self.plt.setBackground('w')
        setConfigOption('foreground', 'k')

        #####self.plt.showGrid( True, True )

        labelStyle = {'color': 'k'}
        self.axs_x.setLabel('Time [s]', **labelStyle)
        self.axs_y.setLabel('Magnetic Field [nT]', **labelStyle)

        self.axs_x.label.setFont(self.fnt)
        self.axs_y.label.setFont(self.fnt)

        self.axs_x.setTickFont(self.fnt)
        self.axs_y.setTickFont(self.fnt)

        self.axs_x.setHeight(35)
        self.axs_y.setWidth(40)

        self.vbx.border = self.pen_vbx

        self.ptm.setContentsMargins(5, 5, 5, 5)

        # Initialize the curves that will be added to this plot.

        self.crv_m = None
        self.crv_n = None
        self.crv_x = None
        self.crv_y = None
        self.crv_z = None
        self.pl = []

        # Populate this plot and adjust it's settings.

        self.make_plt()

    #-----------------------------------------------------------------------
    # DEFINE THE FUNCTION FOR POPULATING THE PLOT.
    #-----------------------------------------------------------------------

    def make_plt(self):

        # Reset the plot (i.e., remove all plot elements).

        self.rset_plt()

        # Establish the ranges of its time and magnetic field values.
        # If the core contains no data or only a single datum,
        # improvise (for the purpose of later establishing axis limits).

        if (self.core.n_mfi >= 1):

            # Establish the domain of the plot.

            t_min = min(amin(self.core.mfi_s), 0.)
            t_max = max(amax(self.core.mfi_s), self.core.fc_spec['dur'])

            # Establish the range of the plot.  As part of this,
            # ensure that the range satisfies a minimum size and has
            # sufficient padding.

            b_max = amax(self.core.mfi_b)
            b_min = -b_max

            d_t_0 = t_max - t_min
            d_b_0 = b_max - b_min

            d_t = max(1.5 + d_t_0, 3.)
            d_b = max(1.2 * d_b_0, 5.)

            t_max = t_min + d_t

            b_min = b_min - (d_b - d_b_0) / 2.
            b_max = b_max + (d_b - d_b_0) / 2.

        else:

            t_min = 0.001
            t_max = 3.500

            b_min = -2.5
            b_max = 2.5

        # Set the range of the axis of each plot.

        self.plt.setXRange(t_min, t_max, padding=0.0)
        self.plt.setYRange(b_min, b_max, padding=0.0)

        # Set the PESA-L pen with a width corresponding to one rotation
        # Note: For some reason, the lines are not wide enough unless 5
        #       is added to the scaled width of the rotation time

        rot = 3.05 * self.axs_x.width() / (t_max - t_min) + 5

        self.pen_pl = mkPen(color=(245, 245, 245), width=rot)

        # If the core contains no Wind/MFI magnetic field data, return.

        if (self.core.n_mfi <= 0):
            return

        # Generate and display each curve for the plot.

        self.crv_m = PlotDataItem(self.core.mfi_s,
                                  self.core.mfi_b,
                                  pen=self.pen_crv_m)
        self.crv_n = PlotDataItem(self.core.mfi_s,
                                  [-b for b in self.core.mfi_b],
                                  pen=self.pen_crv_n)
        self.crv_x = PlotDataItem(self.core.mfi_s,
                                  self.core.mfi_b_x,
                                  pen=self.pen_crv_x)
        self.crv_y = PlotDataItem(self.core.mfi_s,
                                  self.core.mfi_b_y,
                                  pen=self.pen_crv_y)
        self.crv_z = PlotDataItem(self.core.mfi_s,
                                  self.core.mfi_b_z,
                                  pen=self.pen_crv_z)

        # If PESA-L spectra were loaded, add the vertical indicators
        # showing their time relative to the start of the FC spectrum

        for n in range(len(self.core.pl_spec_arr)):

            time = self.core.pl_spec_arr[n]['time'][0]

            t_0 = self.core.fc_spec['time']

            delta_t = (time - t_0).total_seconds()

            self.pl += [
                InfiniteLine(delta_t + self.core.fc_spec['rot'] / 2.,
                             pen=self.pen_pl)
            ]

        for i in range(len(self.pl)):

            self.plt.addItem(self.pl[i])

        self.plt.addItem(self.crv_m)
        self.plt.addItem(self.crv_n)
        self.plt.addItem(self.crv_x)
        self.plt.addItem(self.crv_y)
        self.plt.addItem(self.crv_z)

    #-----------------------------------------------------------------------
    # DEFINE THE FUNCTION FOR RESETTING THIS PLOT (CLEARING ALL ELEMENTS).
    #-----------------------------------------------------------------------

    def rset_plt(self):

        # Hide and remove each of this plot's elements.

        if (self.crv_m is not None):
            self.plt.removeItem(self.crv_m)

        if (self.crv_n is not None):
            self.plt.removeItem(self.crv_n)

        if (self.crv_x is not None):
            self.plt.removeItem(self.crv_x)

        if (self.crv_y is not None):
            self.plt.removeItem(self.crv_y)

        if (self.crv_z is not None):
            self.plt.removeItem(self.crv_z)

        if (self.pl != []):

            for i in range(len(self.pl)):

                self.plt.removeItem(self.pl[i])

        # if ( self.crv_colat is not None ) :
        # 	self.plt.removeItem( self.crv_colat )

        # if ( self.crv_lon is not None ) :
        # 	self.plt.removeItem( self.crv_lon )

        # Permanently delete this plot's elements by setting each of the
        # variables that store them to "None".

        self.crv_m = None
        self.crv_n = None
        self.crv_x = None
        self.crv_y = None
        self.crv_z = None
        self.pl = []

    #-----------------------------------------------------------------------
    # DEFINE THE FUNCTION FOR RESPONDING TO THE "rset" SIGNAL.
    #-----------------------------------------------------------------------

    def resp_rset(self):

        # Reset the plot.

        self.rset_plt()

    #-----------------------------------------------------------------------
    # DEFINE THE FUNCTION FOR RESPONDING TO THE "chng_mfi" SIGNAL.
    #-----------------------------------------------------------------------

    def resp_chng_mfi(self):

        # Regenerate the plot.

        self.make_plt()
コード例 #15
0
class FindPeak(QWidget):
    def __init__(self, parent, x_data, y_data):
        super(FindPeak, self).__init__()
        self.parent = parent
        self.x = x_data
        self.y = y_data
        self.lower = np.min(x_data)
        self.upper = np.max(x_data)
        self.range = self.upper - self.lower
        self.renderWindow()
        self.initPlotView()
        self.drawCurve()
        self.setUpProcessUI()
        self.bindEvents()
        self.integral(x_data, y_data, self.lower, self.upper)

    def bindEvents(self):
        self.bindBoundEvent()
        self.bindAlgorithmEvent()
        self.bindFindEvent()

    def bindBoundEvent(self):
        def leftBoundEvent(x):
            self.lower = x
            upper = self.upper
            self.plotRegion.setRegion([x, upper])
            self.rightBound.setMinimum(x)
            self.peakCenter.setMinimum(x)
            self.peakCenter.setValue((x + upper) / 2)
            self.integral(self.x, self.y, x, upper)

        def rightBoundEvent(x):
            self.upper = x
            lower = self.lower
            self.plotRegion.setRegion([lower, x])
            self.leftBound.setMaximum(x)
            self.peakCenter.setMaximum(x)
            self.peakCenter.setValue((x + lower) / 2)
            self.integral(self.x, self.y, lower, x)

        def regionChangeEvent():
            lower, upper = self.plotRegion.getRegion()
            self.lower = lower
            self.upper = upper
            self.leftBound.setValue(lower)
            self.leftBound.setMaximum(upper)
            self.rightBound.setValue(upper)
            self.rightBound.setMinimum(lower)
            self.peakCenter.setMinimum(lower)
            self.peakCenter.setMaximum(upper)
            self.peakCenter.setValue((lower + upper) / 2)
            self.integral(self.x, self.y, lower, upper)

        self.leftBound.valueChanged.connect(leftBoundEvent)
        self.rightBound.valueChanged.connect(rightBoundEvent)
        self.plotRegion.sigRegionChanged.connect(regionChangeEvent)

    def bindAlgorithmEvent(self):
        def updateInput(a, b, c, d, e, f):
            self.peakWidth.setEnabled(a)
            self.detectDis.setEnabled(b)
            self.noisePrt.setEnabled(c)
            self.amplitude.setEnabled(d)
            self.threshold.setEnabled(e)
            self.findBtn.setEnabled(f)

        def changeAlgorithm(algorithm):
            if algorithm == "Extremum":
                updateInput(False, False, False, False, False, True)
                pass
            elif algorithm == "Matlab Like":
                updateInput(True, True, False, True, True, True)
                pass
            elif algorithm == "Gaussian":
                updateInput(False, False, False, False, False, False)
                pass
            elif algorithm == "Lorentzian":
                updateInput(False, False, False, False, False, False)
                pass
            elif algorithm == "Pseudo-Voigt":
                updateInput(False, False, False, False, False, False)
                pass
            elif algorithm == "Wavelet Transform":
                updateInput(True, True, True, False, False, False)
                pass

        self.algorithm.currentTextChanged.connect(changeAlgorithm)
        updateInput(False, False, False, False, False, True)

    def integral(self, x_data, y_data, lower, upper):
        idx = np.where((x_data >= lower) & (x_data <= upper))
        x = x_data[idx]
        y = y_data[idx]
        self.integralArea.setValue(simps(y, x))

    def bindFindEvent(self):
        x_data = self.x
        y_data = self.y

        def findPeak():
            region = np.where((x_data >= self.lower) & (x_data <= self.upper))
            sub_data = y_data[region]
            sub_region = x_data[region]
            algorithm = self.algorithm.currentText()
            shape = self.shape.currentText()
            if shape == "Peak":
                const = 1
            else:
                const = -1
            sub_data = sub_data * const
            if algorithm == "Extremum":
                peak = np.max(sub_data)
                idx = np.where(sub_data == peak)
                x = sub_region[idx][0]
                y = sub_data[idx][0] * const
                self.peakCenter.setValue(x)
                return self.renderPeakPoint([x, y])
            elif algorithm == "Matlab Like":
                indexes = find_peaks(
                    sub_data,
                    height=self.amplitude.value(),  #低于指定高度忽略
                    threshold=self.threshold.value(),  #相邻两点高度差
                    distance=self.detectDis.value(),  #两峰间距
                    width=self.peakWidth.value()  #峰宽
                )[0]
                if np.size(indexes) == 0:
                    return
                idx = np.where(sub_data == np.max(sub_data[indexes]))
                x = sub_region[idx][0]
                y = sub_data[idx][0] * const
                self.peakCenter.setValue(x)
                return self.renderPeakPoint([x, y])
            elif algorithm == "Wavelet Transform":
                indexes = find_peaks_cwt(
                    sub_data,
                    widths=self.peakWidth.value(),  #峰宽
                    max_distances=self.detectDis.value(),  #两峰间距
                    noise_perc=self.noisePrt.value())[0]
                if np.size(indexes) == 0:
                    return
                idx = np.where(sub_data == np.max(sub_data[indexes]))
                x = sub_region[idx][0]
                y = sub_data[idx][0] * const
                self.peakCenter.setValue(x)
                return self.renderPeakPoint([x, y])
                self.noisePrt
            pass

        self.findBtn.clicked.connect(findPeak)

    def renderPeakPoint(self, pos):
        self.peakPoint.clear()
        self.peakPoint.addPoints([{'pos': pos, 'data': 1}])

    def renderWindow(self):
        #边框结构
        self.setGeometry(80, 80, 800, 420)
        size = self.geometry()
        screen = QDesktopWidget().screenGeometry()
        posX = (screen.width() - size.width()) / 2
        posY = (screen.height() - size.height()) / 2
        self.move(posX, posY)
        #标题
        self.setWindowTitle('Find Peak')
        self.setWindowIcon(QIcon('resource/curve.ico'))
        #布局
        layout = QGridLayout()
        self.graphicsView = QGridLayout()
        layout.addLayout(self.graphicsView, 0, 0, 1, 1)

        self.Process_Box = QGroupBox()
        self.Process_Box.setMinimumSize(200, 420)
        self.Process_Box.setFlat(True)
        layout.addWidget(self.Process_Box, 0, 1, 1, 1)

        self.setLayout(layout)

    def setUpProcessUI(self):
        layout = QGridLayout()
        layout.setContentsMargins(10, 10, 10, 10)
        layout.setSpacing(10)
        self.Process_Box.setLayout(layout)

        layout.addWidget(QLabel(self.translate('Left Boundary')), 0, 0, 1, 1)
        layout.addWidget(QLabel(self.translate('Right Boundary')), 1, 0, 1, 1)
        layout.addWidget(QLabel(self.translate("Integral Area")), 2, 0, 1, 1)
        layout.addWidget(QLabel(self.translate('Peak Center')), 3, 0, 1, 1)
        layout.addWidget(QLabel(self.translate('Peak Shape')), 4, 0, 1, 1)
        layout.addWidget(QLabel(self.translate('Find Peak Algorithm')), 5, 0,
                         1, 1)
        layout.addWidget(QLabel(self.translate('Minimum Peak Width')), 6, 0, 1,
                         1)
        layout.addWidget(QLabel(self.translate('Minimum Detect Distance')), 7,
                         0, 1, 1)
        layout.addWidget(QLabel(self.translate('Noise Percent')), 8, 0, 1, 1)
        layout.addWidget(QLabel(self.translate("Minimum Amplitude")), 9, 0, 1,
                         1)
        layout.addWidget(QLabel(self.translate("Relative Threshold")), 10, 0,
                         1, 1)

        self.leftBound = SpinBox(lower=self.lower, dec=4, val=self.lower)
        self.rightBound = SpinBox(upper=self.upper, dec=4, val=self.upper)
        self.peakCenter = SpinBox(lower=self.lower, upper=self.upper, dec=4)
        self.peakWidth = SpinBox(lower=1, upper=10000, val=5)
        self.noisePrt = SpinBox(lower=0, upper=100, step=1, val=10)
        self.detectDis = SpinBox(lower=1, val=3)
        self.amplitude = SpinBox(lower=-1E5, upper=1E5, dec=4, val=-1)
        self.threshold = SpinBox(lower=0, upper=100, dec=4, val=0.001)
        self.integralArea = SpinBox(upper=1E8, dec=4)
        self.integralArea.setReadOnly(True)
        self.integralArea.setButtonSymbols(QAbstractSpinBox.NoButtons)

        self.shape = QComboBox()
        self.shape.addItems(["Peak", "Valley"])
        #self.shape.currentTextChanged.connect()

        self.algorithm = QComboBox()
        self.algorithm.addItems([
            'Extremum', 'Matlab Like', 'Wavelet Transform', 'Gaussian',
            'Lorentzian', 'Pseudo-Voigt'
        ])
        #self.algorithm.currentTextChanged.connect()
        #https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks_cwt.html
        layout.addWidget(self.leftBound, 0, 1, 1, 1)
        layout.addWidget(self.rightBound, 1, 1, 1, 1)
        layout.addWidget(self.integralArea, 2, 1, 1, 1)
        layout.addWidget(self.peakCenter, 3, 1, 1, 1)
        layout.addWidget(self.shape, 4, 1, 1, 1)
        layout.addWidget(self.algorithm, 5, 1, 1, 1)
        layout.addWidget(self.peakWidth, 6, 1, 1, 1)
        layout.addWidget(self.detectDis, 7, 1, 1, 1)
        layout.addWidget(self.noisePrt, 8, 1, 1, 1)
        layout.addWidget(self.amplitude, 9, 1, 1, 1)
        layout.addWidget(self.threshold, 10, 1, 1, 1)

        self.findBtn = QPushButton(self.translate('Find Peak'))
        layout.addWidget(self.findBtn, 11, 0, 1, 2)
        pass

    def initPlotView(self):
        self.plot = PlotWidget(enableAutoRange=True)
        self.plot.setXRange(self.lower - self.range * 0.05,
                            self.upper + self.range * 0.05)
        self.plotLegand = self.plot.addLegend()
        self.graphicsView.addWidget(self.plot)
        self.plotRegion = LinearRegionItem()
        self.plotRegion.setZValue(10)
        self.peakPoint = ScatterPlotItem(size=8,
                                         pen=mkPen(color='0000FF', width=2),
                                         symbol="+",
                                         brush=mkBrush(255, 255, 255, 240))
        self.plot.addItem(self.plotRegion, ignoreBounds=True)
        self.plot.addItem(self.peakPoint)
        self.setGraphViewStyle()

    def setGraphViewStyle(self):
        self.plot.setAutoVisible(y=True)
        self.plot.setBackground('#ffffff')
        self.plot.showGrid(x=True, y=True, alpha=0.25)
        self.plot.getAxis('bottom').setPen(color='#000000', width=1.5)
        self.plot.getAxis('left').setPen(color='#000000', width=1.5)
        self.plotRegion.setRegion([self.lower, self.upper])
        self.plotRegion.setBounds([self.lower, self.upper])

    def drawCurve(self):
        pen = mkPen(color='FF0000', width=2)
        self.plot.plot(self.x, self.y, pen=pen)
        self.plot.show()

    def translate(self, text):
        if self.parent:
            self.langText = self.parent.langText
        else:
            self.langText = load(open('SCN.translation', encoding='utf-8'))
        if text in self.langText:
            return self.langText[text]
        return text
コード例 #16
0
class ConditionDialog(QDialog):
    """
    Create a new binary column on a set of localizations by 
    drawing a threshold on a 1D histogram of some attribute 
    for those localizations.

    For example, threshold only spots with low intensity (I0)
    or something.

    init
    ----
        locs        :   pandas.DataFrame
        parent      :   root QWidget

    """
    def __init__(self, locs, parent=None):
        super(ConditionDialog, self).__init__(parent=parent)
        self.locs = locs 
        self.initUI()

    def initUI(self):
        """
        Initialize user interface.

        """
        L = QGridLayout(self)
        self.resize(500, 300)

        widget_align = Qt.AlignLeft

        # Available columns for recondition: all numeric columns
        self.columns = list(filter(
            lambda c: self.locs[c].dtype in ['float64', 'float32', \
                'uint8', 'uint16', 'int64'],
            self.locs.columns))

        # For the default, choose `I0` if available; otherwise
        # choose the first column
        init_col = 'I0' if ('I0' in self.columns) else self.columns[0]
        self.load_col(init_col)

        # Main plot
        self.PlotWidget = PlotWidget(name="Create Boolean attribute")
        L.addWidget(self.PlotWidget, 0, 0, alignment=widget_align)

        # Histogram
        self.curve = self.PlotWidget.plot(self.bin_c, self.H, clickable=True)

        # User threshold, as a LinearRegionItem from pyqtgraph
        self.LinearRegion = LinearRegionItem([self.hmin, (self.hmax-self.hmin)*0.25+self.hmin])
        self.PlotWidget.addItem(self.LinearRegion)

        # Drop-down menu to select the column
        self.M_select_col = LabeledQComboBox(self.columns, "Attribute",
            init_value=init_col, parent=self)
        self.M_select_col.assign_callback(self.M_select_col_callback)
        L.addWidget(self.M_select_col, 1, 0, alignment=widget_align)

        # Accept the current threshold
        self.B_accept = QPushButton("Accept", parent=self)
        L.addWidget(self.B_accept, 2, 0, alignment=widget_align)
        self.B_accept.clicked.connect(self.B_accept_callback)

        self.update_histogram()

    def load_col(self, col):
        """
        Get data from a specific column in the locs dataframe.

        args
        ----
            col     :   str

        """
        self.data = np.asarray(self.locs[col])

        # Histogram limits
        self.hmin = self.data.min()
        self.hmax = np.percentile(self.data, 99.9)

        # Binning scheme
        n_bins = 5000
        bin_size = (self.hmax - self.hmin) / n_bins
        self.bin_edges = np.arange(self.hmin, self.hmax, bin_size)

        # Bin the data according to the binning scheme
        self.H, _edges = np.histogram(self.data, bins=self.bin_edges)
        self.bin_c = self.bin_edges[:-1] + (self.bin_edges[1]-self.bin_edges[0])/2.0

    def update_histogram(self):
        """
        Update the main histogram with data from a new column

        """
        self.PlotWidget.clear()
        self.curve = self.PlotWidget.plot(self.bin_c, self.H)
        self.curve.setPen('w')

        # Set default values for linear rect region
        self.LinearRegion.setRegion((self.hmin, np.percentile(self.data, 50)))
        self.PlotWidget.addItem(self.LinearRegion)
        self.curve.updateItems()

    def M_select_col_callback(self):
        """
        Select the current attribute to filter on.

        """
        col = self.M_select_col.currentText()
        self.load_col(col)
        self.update_histogram()

    def B_accept_callback(self):
        """
        Set the return value and exit from the dialog.

        """
        self.return_val = (
            self.LinearRegion.getRegion(),
            self.M_select_col.currentText(),
        )
        self.accept()
コード例 #17
0
class Mark(QMainWindow, Ui_Form):
    def __init__(self):
        super(Mark, self).__init__()
        self.setupUi(self)
        # super(Mark,self).__init__()
        #左上角点100,100, 宽高1000,900, 可自己设置,未利用布局
        # self.setGeometry(100,100,1500,900)
        # self.setWindowTitle("Mark")  #窗口标题
        self.initUI()
        self.image_origin = None
        self.image_ploted = None
        self.result = []
        self.box_width_init = 20
        self.box_height_init = 60
        self.binary_threshold = 150
        self.img_loaded = False
        self.show_binary = False
        self.handle_index = -1

    def buttonClick(self):  #label上显示文字hello world
        print('111111111')

    def initUI(self):
        pass

        # self.labelImg.grabKeyboard()   #控件开始捕获键盘

        self.buttonSave.clicked.connect(self.buttonClick)  #保存按钮关联的时间

        self.editBoxWidth.editingFinished.connect(self.boxWidthChange)
        self.editBoxHeight.editingFinished.connect(self.boxHeightChange)

        allImgs = os.listdir(imgPath)  #遍历路径,将所有文件放到列表框中
        for imgTmp in allImgs:
            self.allFiles.addItem(imgTmp)  # 将此文件添加到列表中
        self.allFiles.itemClicked.connect(
            self.itemClick)  #列表框关联时间,用信号槽的写法方式不起作用

        self.thresholdSlider.valueChanged.connect(self.thresholdUpdate)

        self.radioImageBinary.toggled.connect(self.binaryChecked)

        self.plot_widget = PlotWidget(self)
        self.plot_widget.setGeometry(QtCore.QRect(1230, 450, 200, 200))
        self.width_count = np.zeros(30)
        self.x = np.arange(30)
        y = np.zeros(30)
        bg = pg.BarGraphItem(x=self.x, y=y, height=0, width=0.8)
        self.plot_widget.addItem(bg)
        #self.curve = self.plot_widget.plot(self.width_count, name="mode2")

    def mousePressEvent(self, QMouseEvent):  #鼠标单击事件
        self.handle_index = -1
        if self.img_loaded == False:
            return
        fr = float(self.editR.text())  # 读取缩放比例
        pointT = QMouseEvent.pos()  # 获得鼠标点击处的坐标
        point = [
            int((pointT.x() - 200) / fr + 0.5),
            int((pointT.y() - 70) / fr + 0.5)
        ]

        # for result_ in self.result:
        #     rect = result_['rect']
        #     [[x,y],[w,h],angle] = rect

        #     dif = (x-point[0])*(x-point[0])+(y-point[1])*(y-point[1])
        #     if(dif<1000):
        #         print(dif)

        if (point[0] > 0 and point[1] > 0):
            if QMouseEvent.button() == Qt.LeftButton:
                img = self.image_origin.copy()
                pkg = auto_search(img, [point[0], point[1]],
                                  self.box_width_init,
                                  self.box_height_init,
                                  binary_threshold=self.binary_threshold,
                                  is_show=False)
                # 保存结果
                is_find = pkg['is_find']
                if (is_find):
                    box = pkg['box']
                    rect = pkg['rect']
                    self.result.append({
                        'rect': rect,
                        'box': box,
                        'width': rect[1][1]
                    })

                self.image_ploted = img  # 保存画上图案的图片
                self.imshow()
            elif QMouseEvent.button() == Qt.RightButton:
                min_distance = 99999
                min_idx = -1
                for idx, result in enumerate(self.result):
                    [[x, y], [w, h], angle] = result['rect']
                    dis = (point[0] - x) * (point[0] - x) + (point[1] - y) * (
                        point[1] - y)
                    if (dis < min_distance):
                        min_distance = dis
                        min_idx = idx
                self.handle_index = min_idx
                self.imshow()
                pass

        self.width_count = np.zeros(30)
        for result_ in self.result:
            width = result_['width']
            if (width > 30):  # 暂时认为不存在超过30宽度的毛发,后面改成自适应数组
                continue
            self.width_count[int(width)] += 1

        bg = pg.BarGraphItem(x=self.x, height=self.width_count, width=0.8)
        self.plot_widget.addItem(bg)

    def eventFilter(self, source, event):
        if event.type() == QEvent.MouseMove:
            [x, y] = [event.pos().x(), event.pos().y()]
            #print([x,y])

        return QMainWindow.eventFilter(self, source, event)

    def keyPressEvent(self, QKeyEvent):  # 键盘某个键被按下时调用
        if self.img_loaded == False:
            return
        #参数1  控件
        if (len(self.result) < 1):
            return
        rect = self.result[self.handle_index]['rect']
        [[x, y], [w, h], angle] = rect

        if QKeyEvent.key() == Qt.Key_A:  # 左移
            x -= 1
            rect = ((x, y), (w, h), angle)
            box = cv.boxPoints(rect)
            box = np.int0(box)
            self.result.pop(self.handle_index)
            self.result.append({'rect': rect, 'box': box, 'width': rect[1][1]})
            self.handle_index = -1  # 修正后,对应目标的序号必定变为-1
            self.imshow()

        if QKeyEvent.key() == Qt.Key_D:  # 右移
            x += 1
            rect = ((x, y), (w, h), angle)
            box = cv.boxPoints(rect)
            box = np.int0(box)
            self.result.pop(self.handle_index)
            self.result.append({'rect': rect, 'box': box, 'width': rect[1][1]})
            self.handle_index = -1
            self.imshow()

        if QKeyEvent.key() == Qt.Key_S:  # 下移
            y += 1
            rect = ((x, y), (w, h), angle)
            box = cv.boxPoints(rect)
            box = np.int0(box)
            self.result.pop(self.handle_index)
            self.result.append({'rect': rect, 'box': box, 'width': rect[1][1]})
            self.handle_index = -1
            self.imshow()

        if QKeyEvent.key() == Qt.Key_W:  # 上移
            y -= 1
            rect = ((x, y), (w, h), angle)
            box = cv.boxPoints(rect)
            box = np.int0(box)
            self.result.pop(self.handle_index)
            self.result.append({'rect': rect, 'box': box, 'width': rect[1][1]})
            self.handle_index = -1
            self.imshow()

        if QKeyEvent.key() == Qt.Key_Up:  # 变宽
            h += 1
            rect = ((x, y), (w, h), angle)
            box = cv.boxPoints(rect)
            box = np.int0(box)
            self.result.pop(self.handle_index)
            self.result.append({'rect': rect, 'box': box, 'width': rect[1][1]})
            self.handle_index = -1
            self.imshow()

        if QKeyEvent.key() == Qt.Key_Down:  # 变窄
            h -= 1
            rect = ((x, y), (w, h), angle)
            box = cv.boxPoints(rect)
            box = np.int0(box)
            self.result.pop(self.handle_index)
            self.result.append({'rect': rect, 'box': box, 'width': rect[1][1]})
            self.handle_index = -1
            self.imshow()

        if QKeyEvent.key() == Qt.Key_Left:  # 逆时针旋转
            angle -= 1
            rect = ((x, y), (w, h), angle)
            box = cv.boxPoints(rect)
            box = np.int0(box)
            self.result.pop(self.handle_index)
            self.result.append({'rect': rect, 'box': box, 'width': rect[1][1]})
            self.handle_index = -1
            self.imshow()

        if QKeyEvent.key() == Qt.Key_Right:  # 顺时针旋转
            angle += 1
            rect = ((x, y), (w, h), angle)
            box = cv.boxPoints(rect)
            box = np.int0(box)
            self.result.pop(self.handle_index)
            self.result.append({'rect': rect, 'box': box, 'width': rect[1][1]})
            self.handle_index = -1
            self.imshow()

        if QKeyEvent.key() == Qt.Key_Backspace:  # 删除
            self.result.pop(self.handle_index)
            self.handle_index = -1
            self.imshow()

        if QKeyEvent.modifiers(
        ) == Qt.ControlModifier | Qt.ShiftModifier and QKeyEvent.key(
        ) == Qt.Key_A:  # 三键组合
            print('按下了Ctrl+Shift+A键')

    def boxWidthChange(self):
        self.box_width_init = float(self.editBoxWidth.text())
        self.editBoxWidth.clearFocus()
        return

    def boxHeightChange(self):
        self.box_height_init = float(self.editBoxHeight.text())
        self.editBoxHeight.clearFocus()
        return

    def imshow(self):
        try:
            if (self.show_binary == False):
                img = curve_plot(self.image_origin.copy(), self.result,
                                 (255, 0, 0), self.handle_index)
            else:
                img = cv.cvtColor(self.image_origin.copy(), cv.COLOR_BGR2GRAY)
                _, img = cv.threshold(img, self.binary_threshold, 255,
                                      cv.THRESH_BINARY_INV)
                img = cv.cvtColor(img, cv.COLOR_GRAY2RGB)
                img = curve_plot(img, self.result, (255, 0, 0),
                                 self.handle_index)
                # img = cv.cv
            img = cv.resize(img, self.img_size)
            img = QtGui.QImage(img, img.shape[1], img.shape[0],
                               img.shape[1] * 3, QtGui.QImage.Format_RGB888
                               )  # bytesPerLine参数设置为image的width*image.channels
            self.labelImg.setPixmap(QtGui.QPixmap(img))
        except:  # 未加载图像
            pass

    def binaryChecked(self, isChecked):
        self.show_binary = isChecked
        self.imshow()

    def thresholdUpdate(self, value):
        self.binary_threshold = int(value)
        self.imshow()

    # 单机列表中某张图片,将其选中并显示
    def itemClick(self):  #列表框单击事件
        self.result = []

        tmp = imgPath + self.allFiles.currentItem().text()  #图像的绝对路径
        print(tmp)
        src = cv.imread(str(tmp), 1)  #读取图像
        src = cv.cvtColor(src, cv.COLOR_BGR2RGB)

        self.image_origin = src.copy()
        self.image_ploted = src.copy()

        height = src.shape[0]  #图像高度
        ratioY = self.labelImg.height() / (height + 0.0)  #按高度值缩放
        self.editR.setText(str(ratioY))  # 编辑框记录缩放值

        width = src.shape[1]  # 计算图像宽度,缩放图像
        height2 = self.labelImg.height()
        width2 = int(width * ratioY + 0.5)

        img2 = cv.resize(src, (width2, height2))

        self.img_size = (width2, height2)

        img2 = QtGui.QImage(img2, img2.shape[1], img2.shape[0],
                            img2.shape[1] * 3, QtGui.QImage.Format_RGB888
                            )  # bytesPerLine参数设置为image的width*image.channels
        self.labelImg.setPixmap(QtGui.QPixmap(img2))

        self.img_loaded = True
        self.allFiles.clearFocus()
コード例 #18
0
ファイル: GUI.py プロジェクト: QUAFFquaff/AutoCoach
class Ui_MainWindow(object):
    def __init__(self):

        self._coin_gold0 = QtGui.QPixmap('icons/events/coin_gold0.png')
        self._coin_gold1 = QtGui.QPixmap('icons/events/coin_gold1.png')
        self._coin_gold2 = QtGui.QPixmap('icons/events/coin_gold2.png')
        self._gold_coin = QtGui.QPixmap('icons/events/coin_gold0.png')
        self._grey_coin = QtGui.QPixmap('icons/events/coin_gold1.png')

        self.grey_bar = QtGui.QPixmap('icons/bars/grey_wide.png')
        self.top_bar = QtGui.QPixmap('icons/bars/red_wide.png')
        self.medium_bar = QtGui.QPixmap('icons/bars/yellow_wide.png')
        self.bottom_bar = QtGui.QPixmap('icons/bars/green_wide.png')

        self.green_glow = pg.QtGui.QGraphicsPixmapItem(
            pg.QtGui.QPixmap('icons/glow/Orange-Glow.png'))
        self.orange_glow = pg.QtGui.QGraphicsPixmapItem(
            pg.QtGui.QPixmap('icons/glow/Orange-Glow.png'))
        self.yellow_glow = pg.QtGui.QGraphicsPixmapItem(
            pg.QtGui.QPixmap('icons/glow/Yellow-Glow.png'))

        self.acc_icon_png = QtGui.QPixmap('icons/bars/acc_icon_g.png')
        self.brake_icon_png = QtGui.QPixmap('icons/bars/brake_icon_g.png')
        self.turn_icon_png = QtGui.QPixmap('icons/bars/turn_icon_g.png')
        self.swerve_icon_png = QtGui.QPixmap('icons/bars/swerve_icon_g.png')
        pass

    windowMoved = QtCore.pyqtSignal(QtCore.QPoint)

    def update_flowing_score(self):
        data3 = self.data3
        ptr3 = self.ptr3
        data3[ptr3] = np.random.normal()

        ptr3 += 1
        if ptr3 >= data3.shape[0]:
            tmp = data3
            data3 = np.empty(data3.shape[0] * 2)
            data3[:tmp.shape[0]] = tmp
        self.pen_y.setData(data3[:ptr3])
        self.data3 = data3
        if (data3[ptr3] > 100):
            self.pen_y.setPen(pg.mkPen('r', width=3))
        if (data3[ptr3] < 100):
            self.pen_y.setPen(pg.mkPen('y', width=3))
        self.pen_y.setPos(-ptr3, 0)
        self.ptr3 = ptr3

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(750, 500)
        MainWindow.setTabShape(QtWidgets.QTabWidget.Rounded)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                           QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.centralwidget.sizePolicy().hasHeightForWidth())
        self.centralwidget.setSizePolicy(sizePolicy)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setContentsMargins(5, 10, 5, 0)
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.bar = QtWidgets.QWidget(self.centralwidget)
        self.bar.setMaximumSize(QtCore.QSize(16777215, 30))
        self.bar.setObjectName("bar")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.bar)
        self.horizontalLayout.setContentsMargins(-1, 5, 11, 5)
        self.horizontalLayout.setSpacing(9)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.exit = QtWidgets.QPushButton(self.bar)
        self.exit.setMaximumSize(QtCore.QSize(30, 20))
        self.exit.setText("")
        self.exit.setObjectName("close")
        self.horizontalLayout.addWidget(self.exit)
        self.visit = QtWidgets.QPushButton(self.bar)
        self.visit.setMaximumSize(QtCore.QSize(30, 20))
        self.visit.setText("")
        self.visit.setObjectName("visit")
        self.horizontalLayout.addWidget(self.visit)
        self.mini = QtWidgets.QPushButton(self.bar)
        self.mini.setMaximumSize(QtCore.QSize(30, 20))
        self.mini.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.mini.setText("")
        self.mini.setAutoDefault(False)
        self.mini.setDefault(False)
        self.mini.setFlat(False)
        self.mini.setObjectName("mini")
        self.horizontalLayout.addWidget(self.mini)
        spacerItem = QtWidgets.QSpacerItem(40, 15,
                                           QtWidgets.QSizePolicy.Expanding,
                                           QtWidgets.QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem)
        self.next_page = QtWidgets.QPushButton(self.bar)
        self.next_page.setMaximumSize(QtCore.QSize(85, 30))
        self.next_page.setObjectName("next_page")
        self.horizontalLayout.addWidget(self.next_page)
        self.verticalLayout.addWidget(self.bar)
        self.Menu = QtWidgets.QGridLayout()
        self.Menu.setObjectName("Menu")
        self.down = QtWidgets.QWidget(self.centralwidget)
        self.down.setMinimumSize(QtCore.QSize(0, 130))
        self.down.setMaximumSize(QtCore.QSize(16777215, 130))
        self.down.setObjectName("down")
        self.down.setStyleSheet(
            'QWidget {background-color: #000000; color: yellow;}')
        self.gridLayout_down = QtWidgets.QGridLayout(self.down)
        self.gridLayout_down.setHorizontalSpacing(5)
        self.gridLayout_down.setObjectName("gridLayout_down")
        # pg.setConfigOption('background', '#17191A')
        self.flowing_scores = PlotWidget(self.down)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                           QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.flowing_scores.sizePolicy().hasHeightForWidth())
        self.flowing_scores.setSizePolicy(sizePolicy)
        self.flowing_scores.setMinimumSize(QtCore.QSize(0, 0))
        self.flowing_scores.setMaximumSize(QtCore.QSize(300, 120))
        self.flowing_scores.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.flowing_scores.setObjectName("widget")
        self.gridLayout_down.addWidget(self.flowing_scores, 0, 0, 1, 1)

        self.verticalLayout_4 = QtWidgets.QVBoxLayout()
        self.verticalLayout_4.setObjectName("verticalLayout_4")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.total_coins_img = QtWidgets.QLabel(self.down)
        self.total_coins_img.setMinimumSize(QtCore.QSize(100, 0))
        self.total_coins_img.setObjectName("total_coins_img")
        self.horizontalLayout_2.addWidget(self.total_coins_img)
        self.label_2 = QtWidgets.QLabel(self.down)
        self.label_2.setMinimumSize(QtCore.QSize(60, 40))
        self.label_2.setText("")
        self.label_2.setObjectName("label_2")
        self.horizontalLayout_2.addWidget(self.label_2)
        self.total_coins_score = QtWidgets.QLabel(self.down)
        self.total_coins_score.setMinimumSize(QtCore.QSize(100, 0))
        font = QtGui.QFont()
        font.setPointSize(20)
        font.setBold(True)
        font.setWeight(75)
        self.total_coins_score.setFont(font)
        self.total_coins_score.setObjectName("total_coins_score")
        self.horizontalLayout_2.addWidget(self.total_coins_score)
        self.verticalLayout_4.addLayout(self.horizontalLayout_2)
        self.total_coins = QtWidgets.QLabel(self.down)
        self.total_coins.setMinimumSize(QtCore.QSize(0, 10))
        self.total_coins.setMaximumSize(QtCore.QSize(16777215, 10))
        font = QtGui.QFont()
        font.setBold(True)
        font.setWeight(75)
        self.total_coins.setFont(font)
        self.total_coins.setAlignment(QtCore.Qt.AlignCenter)
        self.total_coins.setObjectName("total_coins")
        self.verticalLayout_4.addWidget(self.total_coins)
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.trip_score_img = QtWidgets.QLabel(self.down)
        self.trip_score_img.setMinimumSize(QtCore.QSize(100, 0))
        self.trip_score_img.setObjectName("trip_score_img")
        self.horizontalLayout_3.addWidget(self.trip_score_img)
        self.label_3 = QtWidgets.QLabel(self.down)
        self.label_3.setMinimumSize(QtCore.QSize(60, 0))
        self.label_3.setText("")
        self.label_3.setObjectName("label_3")
        self.horizontalLayout_3.addWidget(self.label_3)
        self.trip_score_score = QtWidgets.QLabel(self.down)
        self.trip_score_score.setMinimumSize(QtCore.QSize(100, 0))
        font = QtGui.QFont()
        font.setPointSize(20)
        self.trip_score_score.setFont(font)
        self.trip_score_score.setObjectName("trip_score_score")
        self.horizontalLayout_3.addWidget(self.trip_score_score)
        self.verticalLayout_4.addLayout(self.horizontalLayout_3)
        self.trip_score = QtWidgets.QLabel(self.down)
        self.trip_score.setMinimumSize(QtCore.QSize(0, 9))
        self.trip_score.setMaximumSize(QtCore.QSize(250, 10))
        font = QtGui.QFont()
        font.setFamily("Book Antiqua")
        font.setPointSize(10)
        font.setKerning(True)
        self.trip_score.setFont(font)
        self.trip_score.setLayoutDirection(QtCore.Qt.RightToLeft)
        self.trip_score.setAlignment(QtCore.Qt.AlignCenter)
        self.trip_score.setObjectName("trip_score")
        self.verticalLayout_4.addWidget(self.trip_score)
        self.gridLayout_down.addLayout(self.verticalLayout_4, 0, 4, 1, 1)
        self.verticalLayout_2 = QtWidgets.QVBoxLayout()
        self.verticalLayout_2.setObjectName("verticalLayout_2")
        self.verticalLayout_3 = QtWidgets.QVBoxLayout()
        self.verticalLayout_3.setSpacing(1)
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.current_score = QtWidgets.QLabel(self.down)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding,
                                           QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.current_score.sizePolicy().hasHeightForWidth())
        self.current_score.setSizePolicy(sizePolicy)
        self.current_score.setMinimumSize(QtCore.QSize(200, 60))
        self.current_score.setMaximumSize(QtCore.QSize(250, 60))
        font = QtGui.QFont()
        font.setFamily("Brush Script Std")
        font.setPointSize(50)
        font.setBold(False)
        font.setItalic(False)
        font.setWeight(50)
        self.current_score.setFont(font)
        self.current_score.setAlignment(QtCore.Qt.AlignCenter)
        self.current_score.setObjectName("CurrentScore")
        self.verticalLayout_3.addWidget(self.current_score)
        self.current_score_text = QtWidgets.QLabel(self.down)
        self.current_score_text.setMaximumSize(QtCore.QSize(250, 16777215))
        self.current_score_text.setMinimumSize(QtCore.QSize(250, 40))
        font = QtGui.QFont()
        font.setBold(True)
        font.setWeight(75)
        font.setPointSize(15)
        self.current_score_text.setFont(font)
        self.current_score_text.setAlignment(QtCore.Qt.AlignCenter)
        self.current_score_text.setObjectName("label")
        self.verticalLayout_3.addWidget(self.current_score_text)
        self.verticalLayout_2.addLayout(self.verticalLayout_3)
        self.gridLayout_down.addLayout(self.verticalLayout_2, 0, 1, 1, 1)
        # font = QtGui.QFont()
        # font.setPointSize(15)
        # font.setKerning(True)
        # font.setBold(True)
        # font.setFamily("Brush Script Std")
        self.Menu.addWidget(self.down, 4, 0, 1, 1)
        self.line = QtWidgets.QFrame(self.centralwidget)
        self.line.setFrameShadow(QtWidgets.QFrame.Plain)
        self.line.setLineWidth(10)
        self.line.setFrameShape(QtWidgets.QFrame.HLine)
        self.line.setObjectName("line")
        self.Menu.addWidget(self.line, 1, 0, 1, 1)
        self.up = QtWidgets.QWidget(self.centralwidget)
        self.up.setMinimumSize(QtCore.QSize(0, 320))
        self.up.setMaximumSize(QtCore.QSize(16777215, 16777215))
        self.up.setObjectName("up")

        self.up.setStyleSheet(
            'QWidget {background-color: #000000; color: blue;}')
        self.gridLayout_up = QtWidgets.QGridLayout(self.up)
        self.gridLayout_up.setContentsMargins(-1, 0, -1, 0)
        self.gridLayout_up.setHorizontalSpacing(0)
        self.gridLayout_up.setVerticalSpacing(20)
        self.gridLayout_up.setObjectName("gridLayout_up")

        self.brake_bar = QtWidgets.QWidget(self.up)
        self.brake_bar.setMinimumSize(QtCore.QSize(80, 220))
        self.brake_bar.setMaximumSize(QtCore.QSize(80, 250))
        self.brake_bar.setObjectName("brake_bar")
        self.verticalLayout_break = QtWidgets.QVBoxLayout(self.brake_bar)
        self.verticalLayout_break.setContentsMargins(15, 0, 15, 0)
        self.verticalLayout_break.setSpacing(0)
        self.verticalLayout_break.setObjectName("verticalLayout_break")
        self.brake_icon = QtWidgets.QLabel(self.brake_bar)
        self.brake_icon.setMinimumSize(QtCore.QSize(40, 40))
        self.brake_icon.setMaximumSize(QtCore.QSize(40, 40))
        self.brake_icon.setText("")
        self.brake_icon.setObjectName("brake_icon")
        self.verticalLayout_break.addWidget(self.brake_icon)
        self.brake_bar1 = QtWidgets.QLabel(self.brake_bar)
        self.brake_bar1.setText("")
        self.brake_bar1.setObjectName("brake_bar1")
        self.verticalLayout_break.addWidget(self.brake_bar1)
        self.brake_bar2 = QtWidgets.QLabel(self.brake_bar)
        self.brake_bar2.setText("")
        self.brake_bar2.setObjectName("brake_bar2")
        self.verticalLayout_break.addWidget(self.brake_bar2)
        self.brake_bar3 = QtWidgets.QLabel(self.brake_bar)
        self.brake_bar3.setText("")
        self.brake_bar3.setObjectName("brake_bar3")
        self.verticalLayout_break.addWidget(self.brake_bar3)
        self.brake_bar4 = QtWidgets.QLabel(self.brake_bar)
        self.brake_bar4.setObjectName("brake_bar4")
        self.verticalLayout_break.addWidget(self.brake_bar4)
        self.brake_bar5 = QtWidgets.QLabel(self.brake_bar)
        self.brake_bar5.setObjectName("label_4")
        self.verticalLayout_break.addWidget(self.brake_bar5)
        self.gridLayout_up.addWidget(self.brake_bar, 1, 1, 2, 1)
        self.acc_bar = QtWidgets.QWidget(self.up)
        self.acc_bar.setMinimumSize(QtCore.QSize(80, 220))
        self.acc_bar.setMaximumSize(QtCore.QSize(80, 250))
        self.acc_bar.setObjectName("acc_bar")
        self.verticalLayout_acc = QtWidgets.QVBoxLayout(self.acc_bar)
        self.verticalLayout_acc.setContentsMargins(15, 0, 15, 0)
        self.verticalLayout_acc.setSpacing(0)
        self.verticalLayout_acc.setObjectName("verticalLayout_acc")
        self.acc_icon = QtWidgets.QLabel(self.acc_bar)
        self.acc_icon.setMinimumSize(QtCore.QSize(40, 40))
        self.acc_icon.setMaximumSize(QtCore.QSize(40, 40))
        # self.acc_icon.setLayoutDirection(QtCore.Qt.LeftToRight)
        # self.acc_icon.setAutoFillBackground(False)
        # self.acc_icon.setFrameShape(QtWidgets.QFrame.NoFrame)
        # self.acc_icon.setAlignment(QtCore.Qt.AlignJustify | QtCore.Qt.AlignVCenter)
        self.acc_icon.setText("")
        self.acc_icon.setObjectName("acc_icon")
        self.verticalLayout_acc.addWidget(self.acc_icon)
        self.acc_bar1 = QtWidgets.QLabel(self.acc_bar)
        self.acc_bar1.setText("")
        self.acc_bar1.setObjectName("acc_bar1")
        self.verticalLayout_acc.addWidget(self.acc_bar1)
        self.acc_bar2 = QtWidgets.QLabel(self.acc_bar)
        self.acc_bar2.setText("")
        self.acc_bar2.setObjectName("acc_bar2")
        self.verticalLayout_acc.addWidget(self.acc_bar2)
        self.acc_bar3 = QtWidgets.QLabel(self.acc_bar)
        self.acc_bar3.setText("")
        self.acc_bar3.setObjectName("acc_bar3")
        self.verticalLayout_acc.addWidget(self.acc_bar3)
        self.acc_bar4 = QtWidgets.QLabel(self.acc_bar)
        self.acc_bar4.setObjectName("accbar4")
        self.verticalLayout_acc.addWidget(self.acc_bar4)
        self.acc_bar5 = QtWidgets.QLabel(self.acc_bar)
        self.acc_bar5.setObjectName("acc_bar5")
        self.verticalLayout_acc.addWidget(self.acc_bar5)
        self.gridLayout_up.addWidget(self.acc_bar, 1, 0, 2, 1)
        self.turn_bar = QtWidgets.QWidget(self.up)
        self.turn_bar.setMinimumSize(QtCore.QSize(80, 220))
        self.turn_bar.setMaximumSize(QtCore.QSize(80, 250))
        self.turn_bar.setObjectName("turn_bar")
        self.verticalLayout_turn = QtWidgets.QVBoxLayout(self.turn_bar)
        self.verticalLayout_turn.setContentsMargins(15, 0, 15, 0)
        self.verticalLayout_turn.setSpacing(0)
        self.verticalLayout_turn.setObjectName("verticalLayout_turn")
        self.turn_icon = QtWidgets.QLabel(self.turn_bar)
        self.turn_icon.setMinimumSize(QtCore.QSize(40, 40))
        self.turn_icon.setMaximumSize(QtCore.QSize(40, 40))
        self.turn_icon.setText("")
        self.turn_icon.setObjectName("turn_icon")
        self.verticalLayout_turn.addWidget(self.turn_icon)
        self.turn_bar1 = QtWidgets.QLabel(self.turn_bar)
        self.turn_bar1.setText("")
        self.turn_bar1.setObjectName("turn_bar1")
        self.verticalLayout_turn.addWidget(self.turn_bar1)
        self.turn_bar2 = QtWidgets.QLabel(self.turn_bar)
        self.turn_bar2.setText("")
        self.turn_bar2.setObjectName("turn_bar2")
        self.verticalLayout_turn.addWidget(self.turn_bar2)
        self.turn_bar3 = QtWidgets.QLabel(self.turn_bar)
        self.turn_bar3.setText("")
        self.turn_bar3.setObjectName("turn_bar3")
        self.verticalLayout_turn.addWidget(self.turn_bar3)
        self.turn_bar4 = QtWidgets.QLabel(self.turn_bar)
        self.turn_bar4.setObjectName("turn_bar4")
        self.verticalLayout_turn.addWidget(self.turn_bar4)
        self.turn_bar5 = QtWidgets.QLabel(self.turn_bar)
        self.turn_bar5.setObjectName("turn_bar5")
        self.verticalLayout_turn.addWidget(self.turn_bar5)
        self.gridLayout_up.addWidget(self.turn_bar, 1, 5, 2, 1)
        self.swerve_bar = QtWidgets.QWidget(self.up)
        self.swerve_bar.setMinimumSize(QtCore.QSize(80, 220))
        self.swerve_bar.setMaximumSize(QtCore.QSize(80, 250))
        self.swerve_bar.setObjectName("swerve_bar")
        self.verticalLayout_swerve = QtWidgets.QVBoxLayout(self.swerve_bar)
        self.verticalLayout_swerve.setContentsMargins(15, 0, 15, 0)
        self.verticalLayout_swerve.setSpacing(0)
        self.verticalLayout_swerve.setObjectName("verticalLayout_swerve")
        self.swerve_icon = QtWidgets.QLabel(self.swerve_bar)
        self.swerve_icon.setMinimumSize(QtCore.QSize(40, 40))
        self.swerve_icon.setMaximumSize(QtCore.QSize(40, 40))
        self.swerve_icon.setText("")
        self.swerve_icon.setObjectName("swerve_icon")
        self.verticalLayout_swerve.addWidget(self.swerve_icon)
        self.swerve_bar1 = QtWidgets.QLabel(self.swerve_bar)
        self.swerve_bar1.setText("")
        self.swerve_bar1.setObjectName("swerve_bar1")
        self.verticalLayout_swerve.addWidget(self.swerve_bar1)
        self.swerve_bar2 = QtWidgets.QLabel(self.swerve_bar)
        self.swerve_bar2.setText("")
        self.swerve_bar2.setObjectName("swerve_bar2")
        self.verticalLayout_swerve.addWidget(self.swerve_bar2)
        self.swerve_bar3 = QtWidgets.QLabel(self.swerve_bar)
        self.swerve_bar3.setText("")
        self.swerve_bar3.setObjectName("swerve_bar3")
        self.verticalLayout_swerve.addWidget(self.swerve_bar3)
        self.swerve_bar4 = QtWidgets.QLabel(self.swerve_bar)
        self.swerve_bar4.setObjectName("swerve_bar4")
        self.verticalLayout_swerve.addWidget(self.swerve_bar4)
        self.swerve_bar5 = QtWidgets.QLabel(self.swerve_bar)
        self.swerve_bar5.setObjectName("swerve_bar5")
        self.verticalLayout_swerve.addWidget(self.swerve_bar5)
        self.gridLayout_up.addWidget(self.swerve_bar, 1, 6, 2, 1)
        self.gridLayout_up.addWidget(self.acc_bar, 1, 0, 1, 1)

        pg.setConfigOption('background', '#000000')

        self.backCircle = PlotWidget(self.up)
        # self.backCircle = QtWidgets.QWidget(self.up)
        self.backCircle.setMinimumSize(QtCore.QSize(50, 50))
        self.backCircle.setMaximumSize(QtCore.QSize(249, 249))
        self.backCircle.setObjectName("backCircle")
        self.backCircle.getPlotItem().hideAxis('bottom')
        self.backCircle.getPlotItem().hideAxis('left')
        self.backCircleLayout = QtWidgets.QGridLayout(self.backCircle)
        self.backCircleLayout.setContentsMargins(58, 50, 60, 50)
        self.backCircleLayout.setObjectName("backCircleLayout")
        # self.backCircle.setStyleSheet('QWidget {background-color: red; color: blue;}')

        self.feedback = QtWidgets.QLabel(self.backCircle)
        self.feedback.setMinimumSize(QtCore.QSize(50, 50))
        self.feedback.setMaximumSize(QtCore.QSize(320, 320))
        self.feedback.setText("")
        self.feedback.setAlignment(QtCore.Qt.AlignCenter)
        self.feedback.setObjectName("feedback")

        # self.feedback.setStyleSheet('QWidget {background-color: yellow; color: blue;}')
        self.backCircleLayout.addWidget(self.feedback, 0, 0, 1, 1)
        self.gridLayout_up.addWidget(self.backCircle, 0, 3, 2, 1)
        self.Menu.addWidget(self.up, 0, 0, 1, 1)
        self.verticalLayout.addLayout(self.Menu)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 750, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        # these are three control buttons
        self.exit.setFixedSize(15, 15)
        self.visit.setFixedSize(15, 15)
        self.mini.setFixedSize(15, 15)
        self.exit.setStyleSheet(
            '''QPushButton{background:#F76677;border-radius:5px;}QPushButton:hover{background:red;}'''
        )
        self.next_page.setFixedSize(80, 20)
        # self.visit.setStyleSheet('''QPushButton{background:#F7D674;border-radius:5px;}QPushButton:hover{background:yellow;}''')
        # self.mini.setStyleSheet('''QPushButton{background:#6DDF6D;border-radius:5px;}QPushButton:hover{background:green;}''')

        self._badge1 = QtGui.QPixmap('icons/bars/Car.png')
        self._badge2 = QtGui.QPixmap('icons/events/Less_Coins.png')
        # self._badge3 = QtGui.QPixmap('icons/Badges/png/003-bronze-medal.png')

        self.label_3.setPixmap(self._badge1)
        self.label_3.setScaledContents(True)
        self.label_3.setMaximumSize(QtCore.QSize(10, 40))

        self.label_2.setPixmap(self._badge2)
        self.label_2.setScaledContents(True)
        self.label_2.setMaximumSize(QtCore.QSize(20, 30))

        self.total_coins_score.setStyleSheet(
            'QWidget {background-color: #000000; color: yellow;}')
        self.total_coins.setStyleSheet(
            'QWidget {background-color: #000000; color: gray;}')
        self.trip_score_score.setStyleSheet(
            'QWidget {background-color: #000000; color: yellow;}')
        self.trip_score.setStyleSheet(
            'QWidget {background-color: #000000; color: gray;}')
        self.current_score_text.setStyleSheet(
            'QWidget {background-color: #000000; color: gray;}')
        # beautify window
        self.setWindowFlag(QtCore.Qt.FramelessWindowHint)  # hide the boarder
        # self.setWindowOpacity(0.98)
        # self.setAttribute(QtCore.Qt.WA_TranslucentBackground)  # set transparent window

        self.exit.clicked.connect(self.close)  # close window
        self.mini.clicked.connect(self.showMinimized)  # minimum window
        self.windowMoved.connect(self.move)  # move window

        # draw graph of lines
        self.flowing_scores.setDownsampling(mode='peak')
        self.flowing_scores.setClipToView(True)
        self.flowing_scores.setXRange(0, 100)
        self.flowing_scores.setLimits(xMax=0)
        self.pen_y = self.flowing_scores.plot()
        self.pen_y.setPen(pg.mkPen('y', width=3))
        self.data3 = np.empty(10)
        self.ptr3 = 0

        #draw acc icon
        self.acc_icon.setPixmap(self.acc_icon_png)
        self.acc_icon.setScaledContents(True)
        self.acc_icon.setMaximumSize(QtCore.QSize(40, 40))
        self.turn_icon.setPixmap(self.turn_icon_png)
        self.turn_icon.setScaledContents(True)
        self.turn_icon.setMaximumSize(QtCore.QSize(40, 40))
        self.brake_icon.setPixmap(self.brake_icon_png)
        self.brake_icon.setScaledContents(True)
        self.brake_icon.setMaximumSize(QtCore.QSize(40, 40))
        self.swerve_icon.setPixmap(self.swerve_icon_png)
        self.swerve_icon.setScaledContents(True)
        self.swerve_icon.setMaximumSize(QtCore.QSize(40, 40))

        self.setFeedBack(0, 'acc')

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

    def mousePressEvent(self, event):
        if event.button() == QtCore.Qt.LeftButton:
            self.mPos = event.pos()
        event.accept()

    def mouseReleaseEvent(self, event):
        self.mPos = None
        event.accept()

    def mouseMoveEvent(self, event):
        if event.buttons() == QtCore.Qt.LeftButton and self.mPos:
            self.windowMoved.emit(self.mapToGlobal(event.pos() - self.mPos))
        event.accept()

    # set current score and update
    def setCurrentScore(self, score):
        self.current_score.setText(str(score))

    # set Total score for trip
    def setTotalScore(self, score):
        self.trip_score.setText(str(score))

    def setFeedBack(self, level: int, type: str):

        if level == 0:
            self.backCircle.clear()
            self.backCircle.addItem(self.green_glow)
        elif level == 1:
            self.backCircle.clear()
            self.backCircle.addItem(self.yellow_glow)
        elif level == 2:
            self.backCircle.clear()
            self.backCircle.addItem(self.orange_glow)

        self.feedback.setPixmap(self.acc_icon_png)
        if type == 'acc':
            self.feedback.setPixmap(self.acc_icon_png)
            self.feedback.setScaledContents(True)
            self.feedback.setMaximumSize(QtCore.QSize(100, 150))
        elif type == 'brake':
            self.feedback.setPixmap(self.brake_icon_png)
            self.feedback.setScaledContents(True)
            self.feedback.setMaximumSize(QtCore.QSize(100, 150))
        elif type == 'turn':
            self.feedback.setPixmap(self.turn_icon_png)
            self.feedback.setScaledContents(True)
            self.feedback.setMaximumSize(QtCore.QSize(100, 150))
        elif type == 'swerve':
            self.feedback.setPixmap(self.swerve_icon_png)
            self.feedback.setScaledContents(True)
            self.feedback.setMaximumSize(QtCore.QSize(100, 150))
        else:
            self.feedback.clear()

    def setBar(self, level: int, type: str):
        if type == 'acc':
            self.initalface(type)
            self.change_acc_bar(level)
        elif type == 'brake':
            self.initalface(type)
            self.change_brake_bar(level)
        elif type == 'turn':
            self.initalface(type)
            self.change_turn_bar(level)
        elif type == 'swerve':
            self.initalface(type)
            self.change_swerve_bar(level)

    def initalface(self, type: str):
        if type == 'acc':
            self.acc_bar1.setPixmap(self.grey_bar)
            self.acc_bar2.setPixmap(self.grey_bar)
            self.acc_bar3.setPixmap(self.grey_bar)
            self.acc_bar4.setPixmap(self.grey_bar)
            self.acc_bar5.setPixmap(self.grey_bar)
            self.acc_bar1.setScaledContents(True)
            self.acc_bar2.setScaledContents(True)
            self.acc_bar3.setScaledContents(True)
            self.acc_bar4.setScaledContents(True)
            self.acc_bar5.setScaledContents(True)
            self.acc_bar1.setMaximumSize(QtCore.QSize(40, 47))
            self.acc_bar2.setMaximumSize(QtCore.QSize(40, 47))
            self.acc_bar3.setMaximumSize(QtCore.QSize(40, 47))
            self.acc_bar4.setMaximumSize(QtCore.QSize(40, 47))
            self.acc_bar5.setMaximumSize(QtCore.QSize(40, 47))

        elif type == 'turn':
            self.turn_bar1.setPixmap(self.grey_bar)
            self.turn_bar2.setPixmap(self.grey_bar)
            self.turn_bar3.setPixmap(self.grey_bar)
            self.turn_bar4.setPixmap(self.grey_bar)
            self.turn_bar5.setPixmap(self.grey_bar)
            self.turn_bar1.setScaledContents(True)
            self.turn_bar2.setScaledContents(True)
            self.turn_bar3.setScaledContents(True)
            self.turn_bar4.setScaledContents(True)
            self.turn_bar5.setScaledContents(True)
            self.turn_bar1.setMaximumSize(QtCore.QSize(40, 47))
            self.turn_bar2.setMaximumSize(QtCore.QSize(40, 47))
            self.turn_bar3.setMaximumSize(QtCore.QSize(40, 47))
            self.turn_bar4.setMaximumSize(QtCore.QSize(40, 47))
            self.turn_bar5.setMaximumSize(QtCore.QSize(40, 47))

        elif type == 'swerve':
            self.swerve_bar1.setPixmap(self.grey_bar)
            self.swerve_bar2.setPixmap(self.grey_bar)
            self.swerve_bar3.setPixmap(self.grey_bar)
            self.swerve_bar4.setPixmap(self.grey_bar)
            self.swerve_bar5.setPixmap(self.grey_bar)
            self.swerve_bar1.setScaledContents(True)
            self.swerve_bar2.setScaledContents(True)
            self.swerve_bar3.setScaledContents(True)
            self.swerve_bar4.setScaledContents(True)
            self.swerve_bar5.setScaledContents(True)
            self.swerve_bar1.setMaximumSize(QtCore.QSize(40, 47))
            self.swerve_bar2.setMaximumSize(QtCore.QSize(40, 47))
            self.swerve_bar3.setMaximumSize(QtCore.QSize(40, 47))
            self.swerve_bar4.setMaximumSize(QtCore.QSize(40, 47))
            self.swerve_bar5.setMaximumSize(QtCore.QSize(40, 47))

        elif type == 'brake':
            self.brake_bar1.setPixmap(self.grey_bar)
            self.brake_bar2.setPixmap(self.grey_bar)
            self.brake_bar3.setPixmap(self.grey_bar)
            self.brake_bar4.setPixmap(self.grey_bar)
            self.brake_bar5.setPixmap(self.grey_bar)
            self.brake_bar1.setScaledContents(True)
            self.brake_bar2.setScaledContents(True)
            self.brake_bar3.setScaledContents(True)
            self.brake_bar4.setScaledContents(True)
            self.brake_bar5.setScaledContents(True)
            self.brake_bar1.setMaximumSize(QtCore.QSize(40, 47))
            self.brake_bar2.setMaximumSize(QtCore.QSize(40, 47))
            self.brake_bar3.setMaximumSize(QtCore.QSize(40, 47))
            self.brake_bar5.setMaximumSize(QtCore.QSize(40, 47))
            self.brake_bar4.setMaximumSize(QtCore.QSize(40, 47))

    def change_acc_bar(self, level: int):
        if level == 0:
            self.acc_bar1.setPixmap(self.grey_bar)
            self.acc_bar2.setPixmap(self.grey_bar)
            self.acc_bar3.setPixmap(self.bottom_bar)
        elif level == 1:
            self.acc_bar1.setPixmap(self.grey_bar)
            self.acc_bar2.setPixmap(self.medium_bar)
            self.acc_bar3.setPixmap(self.bottom_bar)
        elif level == 2:
            self.acc_bar1.setPixmap(self.top_bar)
            self.acc_bar2.setPixmap(self.medium_bar)
            self.acc_bar3.setPixmap(self.bottom_bar)

        self.acc_bar1.setScaledContents(True)
        self.acc_bar2.setScaledContents(True)
        self.acc_bar3.setScaledContents(True)
        self.acc_bar1.setMaximumSize(QtCore.QSize(40, 47))
        self.acc_bar2.setMaximumSize(QtCore.QSize(40, 47))
        self.acc_bar3.setMaximumSize(QtCore.QSize(40, 47))

    def change_turn_bar(self, level: int):
        if level == 0:
            self.turn_bar1.setPixmap(self.grey_bar)
            self.turn_bar2.setPixmap(self.grey_bar)
            self.turn_bar3.setPixmap(self.bottom_bar)
        elif level == 1:
            self.turn_bar1.setPixmap(self.grey_bar)
            self.turn_bar2.setPixmap(self.medium_bar)
            self.turn_bar3.setPixmap(self.bottom_bar)
        elif level == 2:
            self.turn_bar1.setPixmap(self.top_bar)
            self.turn_bar2.setPixmap(self.medium_bar)
            self.turn_bar3.setPixmap(self.bottom_bar)
        self.turn_bar1.setScaledContents(True)
        self.turn_bar2.setScaledContents(True)
        self.turn_bar3.setScaledContents(True)
        self.turn_bar1.setMaximumSize(QtCore.QSize(40, 47))
        self.turn_bar2.setMaximumSize(QtCore.QSize(40, 47))
        self.turn_bar3.setMaximumSize(QtCore.QSize(40, 47))

    def change_swerve_bar(self, level: int):
        if level == 0:
            self.swerve_bar1.setPixmap(self.grey_bar)
            self.swerve_bar2.setPixmap(self.grey_bar)
            self.swerve_bar3.setPixmap(self.bottom_bar)
        elif level == 1:
            self.swerve_bar1.setPixmap(self.grey_bar)
            self.swerve_bar2.setPixmap(self.medium_bar)
            self.swerve_bar3.setPixmap(self.bottom_bar)
        elif level == 2:
            self.swerve_bar1.setPixmap(self.top_bar)
            self.swerve_bar2.setPixmap(self.medium_bar)
            self.swerve_bar3.setPixmap(self.bottom_bar)
        self.swerve_bar1.setScaledContents(True)
        self.swerve_bar2.setScaledContents(True)
        self.swerve_bar3.setScaledContents(True)
        self.swerve_bar1.setMaximumSize(QtCore.QSize(40, 47))
        self.swerve_bar2.setMaximumSize(QtCore.QSize(40, 47))
        self.swerve_bar3.setMaximumSize(QtCore.QSize(40, 47))

    def change_brake_bar(self, level: int):
        if level == 0:
            self.brake_bar1.setPixmap(self.grey_bar)
            self.brake_bar2.setPixmap(self.grey_bar)
            self.brake_bar3.setPixmap(self.bottom_bar)
        elif level == 1:
            self.brake_bar1.setPixmap(self.grey_bar)
            self.brake_bar2.setPixmap(self.medium_bar)
            self.brake_bar3.setPixmap(self.bottom_bar)
        elif level == 2:
            self.brake_bar1.setPixmap(self.top_bar)
            self.brake_bar2.setPixmap(self.medium_bar)
            self.brake_bar3.setPixmap(self.bottom_bar)
        self.brake_bar1.setScaledContents(True)
        self.brake_bar2.setScaledContents(True)
        self.brake_bar3.setScaledContents(True)
        self.brake_bar1.setMaximumSize(QtCore.QSize(40, 47))
        self.brake_bar2.setMaximumSize(QtCore.QSize(40, 47))
        self.brake_bar3.setMaximumSize(QtCore.QSize(40, 47))

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.next_page.setText(_translate("MainWindow", "Next Page>>"))
        self.total_coins_img.setText(_translate("MainWindow", ""))
        self.total_coins_score.setText(_translate("MainWindow", "27"))
        self.total_coins.setText(_translate("MainWindow", "Total Coins"))
        self.trip_score_img.setText(_translate("MainWindow", ""))
        self.trip_score_score.setText(_translate("MainWindow", "91"))
        self.trip_score.setText(_translate("MainWindow", "Trip Score"))
        self.current_score.setText(_translate("MainWindow", "86"))
        self.current_score_text.setText(
            _translate("MainWindow", "Current Score"))
コード例 #19
0
class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName(_fromUtf8("Form"))
        Form.resize(851, 674)
        Form.setMouseTracking(True)
        Form.setAcceptDrops(False)
        Form.setLayoutDirection(QtCore.Qt.LeftToRight)

        self.ParamPlBel = PlBelPlot(Form)
        self.ParamPlBel.setGeometry(QtCore.QRect(0, 10, 381, 281))

        self.ResPlBel = PlBelPlot(Form)
        self.ResPlBel.setGeometry(QtCore.QRect(470, 10, 381, 281))
        self.ResPlBel.ResPlot = True

        self.convertButton = QtGui.QPushButton(Form)
        self.convertButton.setGeometry(QtCore.QRect(400, 20, 51, 31))

        self.loadButton = QtGui.QPushButton(Form)
        self.loadButton.setGeometry(QtCore.QRect(540, 300, 121, 25))

        self.FunctionPlot = PlotWidget(Form)
        self.FunctionPlot.setGeometry(QtCore.QRect(0, 340, 851, 331))
        self.FunctionPlot.setObjectName(_fromUtf8("FunctionPlot"))
        self.FunctionPlot.function_curve_plot = pg.PlotCurveItem()
        self.FunctionPlot.function_curve_plot.setPen((5, 6))
        self.FunctionPlot.addItem(self.FunctionPlot.function_curve_plot)

        self.spline_degree = QtGui.QSpinBox(Form)
        self.spline_degree.setGeometry(QtCore.QRect(90, 310, 55, 24))
        self.spline_degree.setMinimum(1)
        self.spline_degree.setMaximum(5)

        self.label_k = QtGui.QLabel(Form)
        self.label_k.setGeometry(QtCore.QRect(70, 300, 16, 16))

        self.steps = QtGui.QSpinBox(Form)
        self.steps.setGeometry(QtCore.QRect(790, 300, 55, 24))
        self.steps.setMinimum(100)
        self.steps.setMaximum(5000)
        self.steps.setProperty("value", 400)

        self.label_steps = QtGui.QLabel(Form)
        self.label_steps.setGeometry(QtCore.QRect(680, 300, 111, 31))

        self.x_min = QtGui.QDoubleSpinBox(Form)
        self.x_min.setGeometry(QtCore.QRect(190, 310, 62, 24))
        self.x_min.setProperty("value", self.ParamPlBel.xMin)
        self.x_min.setMinimum(-100000.0)
        self.x_min.setMaximum(100000.0)
        self.x_min.setProperty("value", self.ParamPlBel.xMin)

        self.x_max = QtGui.QDoubleSpinBox(Form)
        self.x_max.setGeometry(QtCore.QRect(310, 310, 62, 24))
        self.x_max.setProperty("value", self.ParamPlBel.xMax)
        self.x_max.setMinimum(-100000.0)
        self.x_max.setMaximum(100000.0)
        self.x_max.setProperty("value", self.ParamPlBel.xMax)

        self.label_x_min = QtGui.QLabel(Form)
        self.label_x_min.setGeometry(QtCore.QRect(150, 300, 41, 16))

        self.label_xmax = QtGui.QLabel(Form)
        self.label_xmax.setGeometry(QtCore.QRect(260, 300, 41, 16))

        self.clear_PlBel_res = QtGui.QPushButton(Form)
        self.clear_PlBel_res.setGeometry(QtCore.QRect(480, 300, 51, 25))

        self.clear_PlBel_param = QtGui.QPushButton(Form)
        self.clear_PlBel_param.setGeometry(QtCore.QRect(10, 300, 51, 25))

        self.ParamToRes = QtGui.QRadioButton(Form)
        self.ParamToRes.setGeometry(QtCore.QRect(400, 70, 51, 20))
        self.ParamToRes.setCheckable(True)
        self.ParamToRes.setChecked(True)

        self.ResToParam = QtGui.QRadioButton(Form)
        self.ResToParam.setGeometry(QtCore.QRect(400, 100, 51, 20))
        self.ResToParam.setChecked(False)

        self.SaveButton = QtGui.QPushButton(Form)
        self.SaveButton.setGeometry(QtCore.QRect(400, 260, 51, 25))

        self.LoadButton = QtGui.QPushButton(Form)
        self.LoadButton.setGeometry(QtCore.QRect(400, 230, 51, 25))

        self.f_module = None
        self.num = 400
        self.PlotFunction()

        self.convertButton.clicked.connect(self.ConvertPlBel)
        self.loadButton.clicked.connect(self.changing_function)
        self.SaveButton.clicked.connect(self.save_model)
        self.LoadButton.clicked.connect(self.load_model)
        self.clear_PlBel_param.clicked.connect(self.ClearParamPlBel)
        self.clear_PlBel_res.clicked.connect(self.ClearResPlBel)
        self.spline_degree.valueChanged[int].connect(self.ParamPlBel.changeK)
        self.spline_degree.valueChanged[int].connect(self.ResPlBel.changeK)
        self.x_min.valueChanged[float].connect(self.ParamPlBel.changeXmin)
        self.x_max.valueChanged[float].connect(self.ParamPlBel.changeXmax)
        self.steps.valueChanged[int].connect(self.changeNum)

        self.retranslateUi(Form)

    @staticmethod
    def f(x):
        """
        функция,для значений которой мы расчитываем правдоподобие и доверие
        """
        return x/(x + 1)*np.exp(-1.58*x/(x + 1))  # np.sin(2*x)*(x**2-5*x+2)

    def PlotFunction(self):
        x_grid = np.linspace(self.ParamPlBel.xMin,
                             self.ParamPlBel.xMax,
                             self.num)
        y_grid = self.f(x_grid)
        self.FunctionPlot.function_curve_plot.setData(x_grid, y_grid)

    def changeNum(self, num):
        if num >= 100 and num <= 5000:
            self.num = num
            self.ParamPlBel.changeNum(num)
            self.ResPlBel.changeNum(num)

    def ClearParamPlBel(self):
        self.ParamPlBel.pl_grid = np.ones(self.ResPlBel.num)
        self.ParamPlBel.bel_grid = np.zeros(self.ResPlBel.num)
        self.ParamPlBel.points_x = np.array([])
        self.ParamPlBel.points_t = np.array([])
        self.ParamPlBel.pointsPlot.clear()
        self.ParamPlBel.distributionPlPlot.clear()
        self.ParamPlBel.distributionBelPlot.clear()
        self.ParamPlBel.distribution = lambda x: np.ones_like(x)
        self.ParamPlBel.plotInterpolation()

    def ClearResPlBel(self):
        self.ResPlBel.pl_grid = np.ones(self.ResPlBel.num)
        self.ResPlBel.bel_grid = np.zeros(self.ResPlBel.num)
        self.ResPlBel.points_x = np.array([])
        self.ResPlBel.points_t = np.array([])
        self.ResPlBel.distributionPlPlot.clear()
        self.ResPlBel.distributionBelPlot.clear()
        self.ResPlBel.distribution = lambda x: np.ones_like(x)
        self.ResPlBel.plotInterpolation()

    def changing_function(self):
        fname = QtWidgets.QFileDialog.getOpenFileName(
                     QtWidgets.QWidget(), "Open file")
        # создаём диалог выбора файла,
        # на выходе имеем имя файла
        print(fname)
        # пробуем поменять функцию собственную f(.) на функцию f(.) из файла,
        # возвращённого диалоговым окном выбора файла
        try:
            fn = load_module_by_path(fname[0])
            self.f = fn.f  # собственно, меняем
            self.f_module = fname
        except (ValueError('Is it function?'), TypeError('May be not?'),
                SyntaxError, NameError, AttributeError):
            # если не получилось поменять и выскочила ошибка
            print("function f(x) not found!")
            # пишем в консоли, что функция
            # f(.) не найдена
        self.PlotFunction()
        self.ConvertPlBel()

    def save_model(self):
        data = {"function": self.f,
                "alpha": self.ParamPlBel.alpha,
                "ParamDistribution": [self.ParamPlBel.points_x,
                                      self.ParamPlBel.points_t],
                "ResDistribution": [self.ResPlBel.points_x,
                                    self.ResPlBel.points_t],
                "Spline": [self.ParamPlBel.k, self.ParamPlBel.s],
                "minX": self.ParamPlBel.xMin,
                "maxX": self.ParamPlBel.xMax,
                "number_of_steps": self.num}
        print(data)
        fname = QtWidgets.QFileDialog.getOpenFileName(
                     QtWidgets.QWidget(), "Open file", filter="*.pickle")
        with open(fname[0] + "2", "wb") as save_file2:
            pickle.dump(self.f_module, save_file2)
        with open(fname[0], 'wb') as save_file:
            pickle.dump(data, save_file)

    def load_model(self):
        fname = QtWidgets.QFileDialog.getOpenFileName(
                     QtWidgets.QWidget(), "Open file", filter="*.pickle")
        with open(fname[0] + "2", "rb") as load_file2:
            _ = load_module_by_path(pickle.load(load_file2))
        with open(fname[0], 'rb') as load_file:
            new_data = pickle.load(load_file)
        self.f = new_data['function']
        self.ParamPlBel.alpha = new_data['alpha']
        self.ResPlBel.alpha = new_data['alpha']
        self.num = new_data['number_of_steps']
        self.ParamPlBel.num = new_data['number_of_steps']
        self.ResPlBel.num = new_data['number_of_steps']
        self.ParamPlBel.points_x = new_data['ParamDistribution'][0]
        self.ParamPlBel.points_t = new_data['ParamDistribution'][1]
        self.ResPlBel.points_x = new_data['ResDistribution'][0]
        self.ResPlBel.points_t = new_data['ResDistribution'][1]
        self.ParamPlBel.k = new_data['Spline'][0]
        self.ParamPlBel.s = new_data['Spline'][1]
        self.ResPlBel.k = new_data['Spline'][0]
        self.ResPlBel.s = new_data['Spline'][1]
        self.ParamPlBel.xMin = new_data['minX']
        self.ParamPlBel.xMax = new_data['maxX']
        self.ParamPlBel.pointsPlot.setData(self.ParamPlBel.points_x,
                                           self.ParamPlBel.points_t)
        self.ResPlBel.pointsPlot.setData(self.ResPlBel.points_x,
                                         self.ResPlBel.points_t)
        self.ConvertPlBel()
        self.PlotFunction()

    def ConvertPlBel(self):
        if self.ParamToRes.isChecked() is True:
            self.SetParamToRes()
            self.ResPlBelPlot()
        elif self.ResToParam.isChecked() is True:
            self.SetResToParam()
            self.ParPlBelPlot()

    def ResPlBelPlot(self):
        """
        посчитаем распределение правдоподобия и доверия значений функции f(x)
        """
        # построим сетку на области
        # определения функции
        x_grid = np.linspace(self.ParamPlBel.xMin,
                             self.ParamPlBel.xMax,
                             self.num)
        # вычислим значения функции в точках сетки
        y = self.f(x_grid)
        # установим для расчёта распределения
        # правдоподобия и доверия значений функции
        self.ResPlBel.xMin = np.min(y)
        # максимальное и минимальное значения
        # из вычисленных на сетке параметра х
        self.ResPlBel.xMax = np.max(y)
        # построим сетку в области
        # значений функции
        y_iterate = np.linspace(self.ResPlBel.xMin,
                                self.ResPlBel.xMax,
                                self.num)
        # обновим распределение правдоподобия
        self.ResPlBel.pl_grid = np.array([])
        # и доверия
        self.ResPlBel.bel_grid = np.array([])
        # начнём вычисления
        for j in range(self.num):
            """
            найдём для каждого y из все х, которые его доставляют, построим
            новую функцию g(x) и будем искать её корни
            """
            g = lambda x: self.f(x) - y_iterate[j]
            roots = g(x_grid)  # сетка значений новой функции g(x)
            sign_roots = np.sign(roots)  # знаки значений функции
            x_pos = np.array([])  # создадим массив корней функции g(x)
            for i in range(self.num-1):
                k = 0  # счётчик позиции для вставки найденного корня
                # если знак значений функции на концах интервала разный,
                # значит на нём есть корень, хотя бы один
                if sign_roots[i]+sign_roots[i+1] == 0:
                    x0 = brentq(g, x_grid[i], x_grid[i + 1])  # найдём корень
                    # вставим корень в массив
                    # корней на позицию k
                    x_pos = np.insert(x_pos, k, x0)
                    k = k + 1  # увеличим счётчик корней на один
            if np.size(x_pos) == 0:  # если корней нет, то
                # правдоподобие значения y_iterate[j] равно нулю
                self.ResPlBel.pl_grid = np.append(self.ResPlBel.pl_grid, 0.0)
                # а доверие  единице
                self.ResPlBel.bel_grid = np.append(self.ResPlBel.bel_grid,
                                                   self.ParamPlBel.theta(0.0))
            else:  # если корни есть, тогда
                self.ResPlBel.pl_grid = np.append(
                    self.ResPlBel.pl_grid,
                    np.max(self.ParamPlBel.distribution(x_pos)))
                # находим из корней тот, правдоподобие которого
                # максимально и приравниваем его правдоподобие
                # правдоподобию соответствующего значения функции
                self.ResPlBel.bel_grid = np.append(
                    self.ResPlBel.bel_grid,
                    np.min(
                        self.ParamPlBel.theta(
                            self.ParamPlBel.distribution(x_pos))))
                # находим из корней тот, доверие которого
                # минимально и приравниваем его доверие доверию
                # соостветствующего значения функции
        self.ResPlBel.plotInterpolation()  # рисуем

    def ParPlBelPlot(self):
        x_grid = np.linspace(self.ParamPlBel.xMin,
                             self.ParamPlBel.xMax,
                             self.num)
        y = self.f(x_grid)
        self.ResPlBel.xMin = np.min(y)
        self.ResPlBel.xMax = np.max(y)
        self.ParamPlBel.pl_grid = self.ResPlBel.distribution(y)
        self.ParamPlBel.bel_grid = self.ResPlBel.theta(
                                                self.ResPlBel.distribution(y))
        self.ParamPlBel.plotInterpolation()

    def SetParamToRes(self):
        self.ParamPlBel.ResPlot = False
        self.ResPlBel.ResPlot = True

    def SetResToParam(self):
        self.ParamPlBel.ResPlot = True
        self.ResPlBel.ResPlot = False

    def retranslateUi(self, Form):
        Form.setWindowTitle(_translate("Form", "PlBel", None))
        self.convertButton.setText(_translate("Form", "<=>", None))
        self.loadButton.setText(_translate("Form", "Load function", None))
        self.label_k.setText(_translate("Form", "k:", None))
        self.label_steps.setText(_translate("Form", "number of steps:", None))
        self.label_x_min.setText(_translate("Form", "X min:", None))
        self.label_xmax.setText(_translate("Form", "X max:", None))
        self.clear_PlBel_res.setText(_translate("Form", "Clear", None))
        self.ParamToRes.setText(_translate("Form", "=>", None))
        self.ResToParam.setText(_translate("Form", "<=", None))
        self.SaveButton.setText(_translate("Form", "Save", None))
        self.LoadButton.setText(_translate("Form", "Load", None))
        self.clear_PlBel_param.setText(_translate("Form", "Clear", None))
コード例 #20
0
ファイル: aditi.py プロジェクト: jerkos/pymzdb
class Aditi(QMainWindow):

    def __init__(self):
        QMainWindow.__init__(self)

        # title
        self.setWindowTitle("Aditi")
        self.setDockOptions(QMainWindow.VerticalTabs | QMainWindow.AnimatedDocks)
        #self.showMaximized()

        # model
        self.rawfiles_by_short_path = {}
        self.xic_by_rawfile_short_path = {}
        self.tic_by_rawfile_short_path = {}
        self.spec_by_rawfile_short_path = {}

        self.inf_line_tic_item = None
        self.curr_scan_id_by_short_path = {}

        # menu
        self.file_menu = self.menuBar().addMenu('&File')
        #self.file_menu.setTearOffEnabled(False)

        open_action = QAction("&Open...", self)
        open_action.setToolTip("Open a rawfile")
        open_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_O))
        self.file_menu.addAction(open_action)
        open_action.triggered.connect(self.show_open_dialog)

        exit_action = QAction("&Exit", self)
        exit_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_Q))
        self.file_menu.addAction(exit_action)
        exit_action.triggered.connect(self.quit)

        self.tab_widget = QTabWidget(self)
        # spectrum plot Widget
        self.graphics_layout_widget = GraphicsLayoutWidget(parent=self.tab_widget)

        self.graphics_layout_widget.keyPressEvent = self.handle_key_press_event

        self.graphics_layout_widget.useOpenGL(False)
        self.graphics_layout_widget.setAntialiasing(False)

        self.plot_widget_tic = self.graphics_layout_widget.addPlot(title="TIC(s)",
                                                                   labels={'left': "Intensity",
                                                                           'bottom': "Retention Time (sec)"})
        self.plot_widget_tic.showGrid(x=True, y=True)

        self.graphics_layout_widget.nextRow()

        self.plot_widget_spectrum = self.graphics_layout_widget.addPlot(title="Spectrum", labels={'left': "Intensity",
                                                                                                  'bottom': "m/z"})
        self.plot_widget_spectrum.showGrid(x=True, y=True)

        # finally add tab
        self.tab_widget.addTab(self.graphics_layout_widget, "Spectrum")

        # Xic plotWidget
        self.plot_widget_xic = PlotWidget(name="MainPlot", labels={'left': "Intensity",
                                                                   'bottom': "Retention Time (sec)"})
        self.plot_widget_xic.showGrid(x=True, y=True)

        self.tab_widget.addTab(self.plot_widget_xic, "Xic extraction")

        self.setCentralWidget(self.tab_widget)

        self.statusBar().showMessage("Ready")

        # dock 1
        self.rawfile_dock_widget = QDockWidget("Rawfiles")
        self.rawfile_table_view = QTableView()
        self.rawfile_table_view.horizontalHeader().setVisible(False)
        self.rawfile_table_view.horizontalHeader().setResizeMode(QHeaderView.ResizeToContents)
        self.rawfile_dock_widget.setWidget(self.rawfile_table_view)

        self.rawfile_model = QStandardItemModel()
        self.rawfile_model.setHorizontalHeaderLabels(["Rawfiles"])
        self.rawfile_table_view.setModel(self.rawfile_model)

        self.rawfile_model.itemChanged.connect(self.item_changed)

        self.addDockWidget(0x2, self.rawfile_dock_widget)

        # xic dock widget extraction parameter
        self.xic_dock_widget = QDockWidget("Xic extraction")

        self.xic_widget = XicWidget()
        self.xic_widget.plotButton.clicked.connect(self.plot)

        self.xic_dock_widget.setWidget(self.xic_widget)
        self.addDockWidget(0x2, self.xic_dock_widget)

    def handle_key_press_event(self, evt):
        if self.inf_line_tic_item is None:
            return

        times = []
        if evt.key() == Qt.Key_Left:
            for rawfile in self.rawfiles_by_short_path.values()[:1]:
                if not rawfile.is_checked:
                    continue
                curr_scan_id = self.curr_scan_id_by_short_path[rawfile.short_path]
                scan_ids = rawfile.reader.rt_by_scan_id_by_ms_level[1].keys()
                idx = scan_ids.index(curr_scan_id)
                times.append(rawfile.reader.rt_by_scan_id_by_ms_level[1][scan_ids[idx - 1]])
                self.curr_scan_id_by_short_path[rawfile.short_path] = scan_ids[idx - 1]

        elif evt.key() == Qt.Key_Right:
            for rawfile in self.rawfiles_by_short_path.values()[:1]:
                if not rawfile.is_checked:
                    continue
                curr_scan_id = self.curr_scan_id_by_short_path[rawfile.short_path]
                scan_ids = rawfile.reader.rt_by_scan_id_by_ms_level[1].keys()
                idx = scan_ids.index(curr_scan_id)
                times.append(rawfile.reader.rt_by_scan_id_by_ms_level[1][scan_ids[idx + 1]])
                self.curr_scan_id_by_short_path[rawfile.short_path] = scan_ids[idx + 1]

        self._plot_spectrum()

        if times:
            self.inf_line_tic_item.setPos(sum(times) / float(len(times)))

    def _plot_spectrum(self):

        self.plot_widget_spectrum.clear()

        min_mz, max_mz = 1e9, 0
        min_int, max_int = 1e10, 0

        for rawfile in self.rawfiles_by_short_path.values():
            if not rawfile.is_checked:
                continue
            scan_id, mzs, intensities = rawfile.reader.get_scan(self.curr_scan_id_by_short_path[rawfile.short_path])
            min_mz = min(min_mz, mzs[0])
            max_mz = max(max_mz, mzs[-1])
            min_int = min(min_int, min(intensities))
            max_int = max(max_int, max(intensities))
            item = BarGraphItem(x=mzs, height=intensities, width=0.01, pen=rawfile.qcolor, brush=rawfile.qcolor)
            self.plot_widget_spectrum.addItem(item)

        self.plot_widget_spectrum.setLimits(xMin=min_mz, xMax=max_mz, yMin=min_int, yMax=max_int)

    def plot_spectrum(self, ev):
        #clear
        if ev.button() == Qt.RightButton:
            return

        self.plot_widget_spectrum.clear()

        vb = self.plot_widget_tic.vb
        mouse_point = vb.mapSceneToView(ev.scenePos())
        t = mouse_point.x()
        if self.inf_line_tic_item is None:
            self.inf_line_tic_item = InfiniteLine(pos=t, angle=90)
            self.plot_widget_tic.addItem(self.inf_line_tic_item)
            self.inf_line_tic_item.setMovable(True)
        else:
            self.inf_line_tic_item.setPos(t)

        min_mz, max_mz = 1e9, 0
        min_int, max_int = 1e10, 0

        for rawfile in self.rawfiles_by_short_path.values():
            if not rawfile.is_checked:
                continue
            scan_id, mzs, intensities = rawfile.reader.get_scan_for_time(t)
            self.curr_scan_id_by_short_path[rawfile.short_path] = scan_id
            min_mz = min(min_mz, mzs[0])
            max_mz = max(max_mz, mzs[-1])
            min_int = min(min_int, min(intensities))
            max_int = max(max_int, max(intensities))
            item = BarGraphItem(x=mzs, height=intensities, width=0.01, pen=rawfile.qcolor, brush=rawfile.qcolor)
            self.plot_widget_spectrum.addItem(item)

        self.plot_widget_spectrum.setLimits(xMin=min_mz, xMax=max_mz, yMin=min_int, yMax=max_int)

    def item_changed(self, item):
        print "item changed", item.text()
        s = item.text()
        if item.checkState():
            self.rawfiles_by_short_path[s].is_checked = True
        else:
            self.rawfiles_by_short_path[s].is_checked = False
        #self.qApp.emit(SIGNAL('redraw()'))
        self.update_plot_()

    def show_open_dialog(self):
        files = QFileDialog(self).getOpenFileNames()
        if files:
            preload = Preloader(files, self)
            preload.loaded.connect(self.update_rawfile_model)
            preload.start()

    def update_rawfile_model(self, obj):
        files, r = obj[0], obj[1]
        n = len(files)
        not_database = []
        min_time, max_time = 1e9, 0
        min_int, max_int = 1e9, 0
        for i, f in enumerate(files):
            i_f = float(i)
            c = WithoutBlank.get_color(i_f / n, asQColor=True)
            c_ = WithoutBlank.get_color(i_f / n, asQColor=True)
            filename = f.split("\\")[-1]
            abs_path = str(f.replace("\\", "\\\\"))
            if r[i]:
                rawfile = Rawfile(abs_path, c, filename)
                self.rawfiles_by_short_path[filename] = rawfile   #[MzDBReader(abs_path), c, True]
                self.rawfile_model.appendRow(Aditi.get_coloured_root_item(filename, c, c_))

                times, intensities = rawfile.reader.get_tic()
                min_time = min(min_time, min(times))
                max_time = max(max_time, max(times))
                min_int = min(min_int, min(intensities))
                max_int = max(max_int, max(intensities))
                self.plot_widget_tic.plot(times, intensities, pen=mkPen(color=rawfile.qcolor, width=1.3))

            else:
                not_database.append(str(filename))

        self.plot_widget_tic.setLimits(xMin=min_time, xMax=max_time, yMin=min_int, yMax=max_int)
        self.plot_widget_tic.scene().sigMouseClicked.connect(self.plot_spectrum)

        if not_database:
            v = "\n".join(not_database)
            QMessageBox.information(self, "Error",
                                    "The following files are not valid sqlite database:\n" + v)

    @staticmethod
    def get_coloured_root_item(filepath, color, colorr):
        root = QStandardItem(filepath)
        gradient = QLinearGradient(-100, -100, 100, 100)
        gradient.setColorAt(0.7, colorr)
        gradient.setColorAt(1, color)
        root.setBackground(QBrush(gradient))
        root.setEditable(False)
        root.setCheckState(Qt.Checked)
        root.setCheckable(True)
        return root

    def quit(self):
        res = QMessageBox.warning(self, "Exiting...", "Are you sure ?", QMessageBox.Ok | QMessageBox.Cancel)
        if res == QMessageBox.Cancel:
            return
        QtGui.qApp.quit()

    def plot(self):
        #clear pw
        self.plot_widget_xic.clear()

        # check sample checked
        checked_files = [rawfile for rawfile in self.rawfiles_by_short_path.values() if rawfile.is_checked]
        mz = self.xic_widget.mzSpinBox.value()
        mz_tol = self.xic_widget.mzTolSpinBox.value()

        mz_diff = mz * mz_tol / 1e6
        min_mz, max_mz = mz - mz_diff, mz + mz_diff

        #Thread implementation not as fast
        # args = [(data[0], min_mz, max_mz, data[2]) for data in checked_files]
        # extractor_thread = Extractor(args, self)
        # extractor_thread.extracted.connect(self._plot)
        # extractor_thread.start()

        min_time_val, max_time_val = 10000, 0
        min_int_val, max_int_val = 1e9, 0
        for rawfile in checked_files:
            t1 = time.clock()
            times, intensities = rawfile.reader.get_xic(min_mz, max_mz)
            print "elapsed: ", time.clock() - t1
            # min_time_val = min(min_time_val, times[0])
            # max_time_val = max(max_time_val, times[-1])
            # min_int_val = min(min_int_val, min(intensities))
            # max_int_val = max(max_int_val, max(intensities))

            item = self.plot_widget_xic.plot(times, intensities, pen=mkPen(color=rawfile.qcolor, width=1.3))
            item.curve.setClickable(True)

            def on_curve_clicked():
                if not rawfile.is_highlighted:
                    item.setPen(mkPen(color=rawfile.qcolor, width=4))
                    rawfile.is_highlighted = True
                else:
                    item.setPen(mkPen(color=rawfile.qcolor, width=2))
                    rawfile.is_highlighted = False

            item.sigClicked.connect(on_curve_clicked)
            #item.sigHovered = on_curve_clicked

            self.xic_by_rawfile_short_path[rawfile.short_path] = item
            self.plot_widget_xic.setTitle(title="Xic@" + str(mz))
            #self.plot_widget_xic.setLimits(xMin=min_time_val, xMax=max_time_val, yMin=min_int_val, yMax=max_int_val)

    def update_plot_(self):
        for rawfile in self.rawfiles_by_short_path.viewvalues():
            if rawfile.is_checked:
                try:
                    self.plot_widget_xic.addItem(self.xic_by_rawfile_short_path[rawfile.short_path])
                except KeyError:
                    mz = self.xic_widget.mzSpinBox.value()
                    mz_tol = self.xic_widget.mzTolSpinBox.value()

                    mz_diff = mz * mz_tol / 1e6
                    min_mz, max_mz = mz - mz_diff, mz + mz_diff
                    times, intensities = rawfile.reader.get_xic(min_mz, max_mz)
                    item = self.plot_widget_xic.plot(times, intensities, pen=mkPen(color=rawfile.qcolor, width=2))
                    self.xic_by_rawfile_short_path[rawfile.short_path] = item
            else:
                try:
                    #self.plot_widget_xic.removeItem(self.xic_by_rawfile_short_path[rawfile.short_path])
                    self.xic_by_rawfile_short_path[rawfile.short_path].hide()
                except KeyError:
                    pass
コード例 #21
0
class PyQtGraphDataPlot(QWidget):

    limits_changed = Signal()

    def __init__(self, parent=None):
        super(PyQtGraphDataPlot, self).__init__(parent)
        self._plot_widget = PlotWidget()
        self._plot_widget.getPlotItem().addLegend()
        self._plot_widget.setBackground((255, 255, 255))
        self._plot_widget.setXRange(0, 10, padding=0)
        vbox = QVBoxLayout()
        vbox.addWidget(self._plot_widget)
        self.setLayout(vbox)
        self._plot_widget.getPlotItem().sigRangeChanged.connect(
            self.limits_changed)

        self._curves = {}
        self._current_vline = None

    def add_curve(self,
                  curve_id,
                  curve_name,
                  curve_color=QColor(Qt.blue),
                  markers_on=False):
        pen = mkPen(curve_color, width=1)
        symbol = "o"
        symbolPen = mkPen(QColor(Qt.black))
        symbolBrush = mkBrush(curve_color)
        # this adds the item to the plot and legend
        if markers_on:
            plot = self._plot_widget.plot(name=curve_name,
                                          pen=pen,
                                          symbol=symbol,
                                          symbolPen=symbolPen,
                                          symbolBrush=symbolBrush,
                                          symbolSize=4)
        else:
            plot = self._plot_widget.plot(name=curve_name, pen=pen)
        self._curves[curve_id] = plot

    def remove_curve(self, curve_id):
        curve_id = str(curve_id)
        if curve_id in self._curves:
            self._plot_widget.removeItem(self._curves[curve_id])
            del self._curves[curve_id]
            self._update_legend()

    def _update_legend(self):
        # clear and rebuild legend (there is no remove item method for the legend...)
        self._plot_widget.clear()
        self._plot_widget.getPlotItem().legend.items = []
        for curve in self._curves.values():
            self._plot_widget.addItem(curve)
        if self._current_vline:
            self._plot_widget.addItem(self._current_vline)

    def redraw(self):
        pass

    def set_values(self, curve_id, data_x, data_y):
        curve = self._curves[curve_id]
        curve.setData(data_x, data_y)

    def vline(self, x, color):
        if self._current_vline:
            self._plot_widget.removeItem(self._current_vline)
        self._current_vline = self._plot_widget.addLine(x=x, pen=color)

    def set_xlim(self, limits):
        # TODO: this doesn't seem to handle fast updates well
        self._plot_widget.setXRange(limits[0], limits[1], padding=0)

    def set_ylim(self, limits):
        self._plot_widget.setYRange(limits[0], limits[1], padding=0)

    def get_xlim(self):
        x_range, _ = self._plot_widget.viewRange()
        return x_range

    def get_ylim(self):
        _, y_range = self._plot_widget.viewRange()
        return y_range
コード例 #22
0
class RTBSA(QMainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.help_menu = self.menuBar().addMenu("&Help")
        self.file_menu = self.menuBar().addMenu("&File")
        self.status_text = QLabel()
        self.plot = PlotWidget(alpha=0.75)
        self.ui = Ui_RTBSA()
        self.ui.setupUi(self)
        self.setWindowTitle('Real Time BSA')
        self.loadStyleSheet()
        self.setUpGraph()

        self.bsapvs = [
            'GDET:FEE1:241:ENRC', 'GDET:FEE1:242:ENRC', 'GDET:FEE1:361:ENRC',
            'GDET:FEE1:362:ENRC'
        ]

        self.populateBSAPVs()
        self.connectGuiFunctions()

        # Initial number of points
        self.numPoints = 2800

        # Initial number of standard deviations
        self.stdDevstoKeep = 3.0

        # 20ms polling time
        self.updateTime = 50

        # Set initial polynomial fit to 2
        self.fitOrder = 2

        self.disableInputs()
        self.abort = True

        # Used to update plot
        self.timer = QTimer(self)

        # self.ratePV = PV('IOC:IN20:EV01:RG01_ACTRATE')
        self.ratePV = PV("EVNT:SYS0:1:LCLSBEAMRATE")

        self.menuBar().setStyleSheet(
            'QWidget{background-color:grey;color:purple}')
        self.create_menu()
        self.create_status_bar()

        # The PV names
        self.devices = {"A": "", "B": ""}

        self.pvObjects = {"A": None, "B": None}

        # The raw, unsynchronized, unfiltered buffers
        self.rawBuffers = {"A": empty(2800), "B": empty(2800)}

        # The times when each buffer finished its last data acquisition
        self.timeStamps = {"A": None, "B": None}

        self.synchronizedBuffers = {"A": empty(2800), "B": empty(2800)}

        # Versions of data buffers A and B that are filtered by standard
        # deviation. Didn't want to edit those buffers directly so that we could
        # unfilter or refilter with a different number more efficiently
        self.filteredBuffers = {"A": empty(2800), "B": empty(2800)}

        # Text objects that appear on the plot
        self.text = {"avg": None, "std": None, "slope": None, "corr": None}

        # All things plot related!
        self.plotAttributes = {
            "curve": None,
            "fit": None,
            "parab": None,
            "frequencies": None
        }

        # Used for the kill swtich
        self.counter = {"A": 0, "B": 0}

        # Used to implement scrolling for time plots
        self.currIdx = {"A": 0, "B": 0}

    def getRate(self):
        # return rtbsaUtils.rateDict[self.ratePV.value]
        return self.ratePV.value

    def disableInputs(self):
        self.ui.fitOrder.setDisabled(True)
        self.ui.searchInputA.setDisabled(True)
        self.ui.searchInputB.setDisabled(True)
        self.ui.labelFitOrder.setDisabled(True)
        self.ui.bsaListA.setDisabled(True)
        self.ui.bsaListB.setDisabled(True)
        self.statusBar().showMessage('Hi there!  I missed you!')
        self.ui.checkBoxPolyFit.setChecked(False)

    def populateBSAPVs(self):
        # Generate list of BSA PVS
        try:
            BSAPVs = check_output(
                ['eget', '-ts', 'ds', '-a',
                 'tag=LCLS.BSA.rootnames']).splitlines()[1:-1]
            self.bsapvs.extend(BSAPVs)

        # Backup for eget error
        except CalledProcessError:
            print("Unable to pull most recent PV list")
            # bsaPVs is pulled from the Constants file
            self.bsapvs.extend(rtbsaUtils.bsaPVs)

        # TODO un-hardcode machine and add common SPEAR PV's
        except OSError:
            print "Other machines coming soon to an RTBSA near you!"
            pass

        for pv in self.bsapvs:
            self.ui.bsaListA.addItem(pv)
            self.ui.bsaListB.addItem(pv)

    def connectGuiFunctions(self):
        # enter 1 is the text input box for device A, and 2 is for B
        QObject.connect(self.ui.searchInputA,
                        SIGNAL("textChanged(const QString&)"), self.searchA)
        QObject.connect(self.ui.searchInputB,
                        SIGNAL("textChanged(const QString&)"), self.searchB)

        # Changes the text in the input box to match the selection from the list
        self.ui.bsaListA.itemClicked.connect(self.setEnterA)
        self.ui.bsaListB.itemClicked.connect(self.setEnterB)

        # Dropdown menu for device A (add common BSA PV's)
        self.ui.dropdownA.addItems(rtbsaUtils.commonlist)

        # Make bunch length default selection
        index = rtbsaUtils.commonlist.index("BLEN:LI24:886:BIMAX")
        self.ui.dropdownA.setCurrentIndex(index)

        self.ui.dropdownA.activated.connect(self.inputActivated)

        # Dropdown menu for device B
        self.ui.dropdownB.addItems(rtbsaUtils.commonlist)
        self.ui.dropdownB.activated.connect(self.inputActivated)

        # All the checkboxes in the Settings section
        self.ui.checkBoxAvsT.clicked.connect(self.AvsTClick)
        self.ui.checkBoxBvsA.clicked.connect(self.AvsBClick)
        self.ui.checkBoxFFT.clicked.connect(self.AFFTClick)
        self.ui.checkBoxShowAve.clicked.connect(self.avg_click)
        self.ui.checkBoxShowStdDev.clicked.connect(self.std_click)
        self.ui.checkBoxCorrCoeff.clicked.connect(self.corr_click)
        self.ui.checkBoxPolyFit.clicked.connect(self.parab_click)
        self.ui.checkBoxLinFit.clicked.connect(self.line_click)
        self.ui.checkBoxShowGrid.clicked.connect(self.showGrid)

        # All the buttons in the Controls section
        self.ui.startButton.clicked.connect(self.initializePlot)
        self.ui.stopButton.clicked.connect(self.stop)
        self.ui.lclsLogButton.clicked.connect(self.logbook)
        self.ui.mccLogButton.clicked.connect(self.MCCLog)

        # fitedit is the text input box for "Order"
        self.ui.fitOrder.returnPressed.connect(self.fitOrderActivated)

        # The radio buttons that enable the dropdown menus
        self.ui.dropdownButtonA.clicked.connect(self.common_1_click)
        self.ui.dropdownButtonB.clicked.connect(self.common_2_click)

        # The radio buttons that enable the search bars
        self.ui.searchButtonA.clicked.connect(self.enter_1_click)
        self.ui.searchButtonB.clicked.connect(self.enter_2_click)

        # Pressing enter in the text input boxes for points and std dev triggers
        # updating the plot
        self.ui.numPoints.returnPressed.connect(self.points_entered)
        self.ui.numStdDevs.returnPressed.connect(self.stdDevEntered)

        # Triggers a redrawing upon pressing enter in the search bar.
        # Proper usage should be using the search bar to search, and selecting
        # from the results in the list. If it's not in the list, it's an invalid
        # PV with no reason to attempt plotting
        self.ui.searchInputA.returnPressed.connect(self.inputActivated)
        self.ui.searchInputB.returnPressed.connect(self.inputActivated)

    def showGrid(self):
        self.plot.showGrid(self.ui.checkBoxShowGrid.isChecked(),
                           self.ui.checkBoxShowGrid.isChecked())

    def setUpGraph(self):
        layout = QGridLayout()
        self.ui.widgetPlot.setLayout(layout)
        layout.addWidget(self.plot, 0, 0)
        self.plot.showGrid(1, 1)

    def loadStyleSheet(self):
        currDir = path.abspath(path.dirname(__file__))
        cssFile = path.join(currDir, "style.css")
        try:
            with open(cssFile, "r") as f:
                self.setStyleSheet(f.read())
        except IOError:
            print("Error loading style sheet")
            pass

    def create_status_bar(self):
        palette = QPalette()
        palette.setColor(palette.Foreground, Qt.magenta)
        self.statusBar().addWidget(self.status_text, 1)
        self.statusBar().setPalette(palette)

    # Effectively an autocomplete
    def search(self, enter, widget):
        widget.clear()
        query = str(enter.text())
        for pv in self.bsapvs:
            if query.lower() in pv.lower():
                widget.addItem(pv)

    def searchA(self):
        self.search(self.ui.searchInputA, self.ui.bsaListA)

    def searchB(self):
        self.search(self.ui.searchInputB, self.ui.bsaListB)

    def setEnter(self, widget, enter, search, enter_rb):
        selection = widget.currentItem()
        enter.textChanged.disconnect()
        enter.setText(selection.text())
        QObject.connect(enter, SIGNAL("textChanged(const QString&)"), search)

        if not self.abort and enter_rb.isChecked():
            self.stop()
            self.timer.singleShot(250, self.initializePlot)

    def setEnterA(self):
        self.setEnter(self.ui.bsaListA, self.ui.searchInputA, self.searchA,
                      self.ui.searchButtonA)

    def setEnterB(self):
        self.setEnter(self.ui.bsaListB, self.ui.searchInputB, self.searchB,
                      self.ui.searchButtonB)

    def correctInput(self, errorMessage, acceptableTxt, textBox):
        self.statusBar().showMessage(errorMessage, 6000)
        textBox.setText(acceptableTxt)

    def correctNumpoints(self, errorMessage, acceptableValue):
        self.correctInput(errorMessage, str(acceptableValue),
                          self.ui.numPoints)
        self.numPoints = acceptableValue

    def correctStdDevs(self, errorMessage, acceptableValue):
        self.correctInput(errorMessage, str(acceptableValue),
                          self.ui.numStdDevs)
        self.stdDevstoKeep = acceptableValue

    def stdDevEntered(self):
        try:
            self.stdDevstoKeep = float(self.ui.numStdDevs.text())
            if self.stdDevstoKeep <= 0:
                raise ValueError
        except ValueError:
            self.correctStdDevs('Enter a float > 0', 3.0)
            return

    def points_entered(self):
        try:
            self.numPoints = int(self.ui.numPoints.text())
        except ValueError:
            self.correctNumpoints('Enter an integer, 1 to 2800', 120)
            return

        if self.numPoints > 2800:
            self.correctNumpoints('Max # points is 2800', 2800)
            return

        if self.numPoints < 1:
            self.correctNumpoints('Min # points is 1', 1)
            return

        self.reinitialize_plot()

    ############################################################################
    # Where the magic happens (well, where it starts to happen). This
    # initializes the BSA plotting and then starts a timer to update the plot.
    ############################################################################
    def initializePlot(self):
        plotTypeIsValid = (self.ui.checkBoxAvsT.isChecked()
                           or self.ui.checkBoxBvsA.isChecked()
                           or self.ui.checkBoxFFT.isChecked())

        if not plotTypeIsValid:
            self.statusBar().showMessage(
                'Pick a Plot Type (PV vs. time '
                'or B vs A)', 10000)
            return

        self.ui.startButton.setDisabled(True)
        self.abort = False

        self.cleanPlot()
        self.pvObjects["A"], self.pvObjects["B"] = None, None

        # Plot history buffer for one PV
        if self.ui.checkBoxAvsT.isChecked():
            if self.populateDevices(self.ui.dropdownButtonA, self.ui.dropdownA,
                                    self.ui.searchButtonA,
                                    self.ui.searchInputA, "A"):
                self.genPlotAndSetTimer(self.genTimePlotA,
                                        self.updateTimePlotA)

        # Plot for 2 PVs
        elif self.ui.checkBoxBvsA.isChecked():
            if self.updateValsFromInput():
                self.genPlotAndSetTimer(self.genPlotAB, self.updatePlotAB)

        # Plot power spectrum
        else:
            if self.populateDevices(self.ui.dropdownButtonA, self.ui.dropdownA,
                                    self.ui.searchButtonA,
                                    self.ui.searchInputA, "A"):
                self.genPlotAndSetTimer(self.InitializeFFTPlot,
                                        self.updatePlotFFT)

    def populateDevices(self, common_rb, common, enter_rb, enter, device):

        if common_rb.isChecked():
            self.devices[device] = str(common.currentText())

        elif enter_rb.isChecked():
            pv = str(enter.text()).strip()

            # Checks that it's non empty and that it's a BSA pv
            if pv and pv in self.bsapvs:
                self.devices[device] = pv
            else:
                self.printStatus('Device ' + device + ' invalid. Aborting.')
                self.ui.startButton.setEnabled(True)
                return False

        return True

    def printStatus(self, message, printToXterm=True):
        if printToXterm:
            print message

        self.statusBar().showMessage(message)

    def updateValsFromInput(self):

        if not self.populateDevices(self.ui.dropdownButtonA, self.ui.dropdownA,
                                    self.ui.searchButtonA,
                                    self.ui.searchInputA, "A"):
            return False

        if not self.populateDevices(self.ui.dropdownButtonB, self.ui.dropdownB,
                                    self.ui.searchButtonB,
                                    self.ui.searchInputB, "B"):
            return False

        self.printStatus("Initializing/Synchronizing " + self.devices["A"] +
                         " vs. " + self.devices["B"] + " buffers...")

        self.initializeBuffers()

        return True

    def initializeBuffers(self):
        # Initial population of our buffers using the HSTBR PV's in our
        # callback functions
        self.clearAndUpdateCallbacks("HSTBR", resetTime=True)

        while ((not self.timeStamps["A"] or not self.timeStamps["B"])
               and not self.abort):
            QApplication.processEvents()

        self.adjustSynchronizedBuffers(True)

        # Switch to BR PVs to avoid pulling an entire history buffer on every
        # update.
        self.clearAndUpdateCallbacks("BR", resetRawBuffer=True)

    def clearAndUpdateCallbacks(self,
                                suffix,
                                resetTime=False,
                                resetRawBuffer=False):
        self.clearAndUpdateCallback("A", suffix, self.callbackA,
                                    self.devices["A"], resetTime,
                                    resetRawBuffer)
        self.clearAndUpdateCallback("B", suffix, self.callbackB,
                                    self.devices["B"], resetTime,
                                    resetRawBuffer)

    # noinspection PyTypeChecker
    def clearAndUpdateCallback(self,
                               device,
                               suffix,
                               callback,
                               pvName,
                               resetTime=False,
                               resetRawBuffer=False):
        self.clearPV(device)

        # Without the time parameter, we wouldn't get the timestamp
        self.pvObjects[device] = PV(pvName + suffix, form='time')

        if resetTime:
            self.timeStamps[device] = None

        # Make sure that the initial raw buffer is synchronized and pad with
        # nans if it's less than 2800 points long
        if resetRawBuffer:
            nanArray = empty(2800 - self.synchronizedBuffers[device].size)
            nanArray[:] = nan
            self.rawBuffers[device] = \
                concatenate([self.synchronizedBuffers[device], nanArray])

        self.pvObjects[device].add_callback(callback)

    # Callback function for Device A
    # noinspection PyUnusedLocal
    def callbackA(self, pvname=None, value=None, timestamp=None, **kw):
        self.updateTimeAndBuffer("A", pvname, timestamp, value)

    # Callback function for Device B
    # noinspection PyUnusedLocal
    def callbackB(self, pvname=None, value=None, timestamp=None, **kw):
        self.updateTimeAndBuffer("B", pvname, timestamp, value)

    ############################################################################
    # This is where the data is actually acquired and saved to the buffers.
    # Callbacks are effectively listeners that listen for change, so we
    # basically put a callback on the PVs of interest (devices A and/or B) so
    # that every time the value of that PV changes, we get that new value and
    # append it to our raw data buffer for that device.
    # Initialization of the buffer is slightly different in that the listener is
    # put on the history buffer of that PV (denoted by the HSTBR suffix), so
    # that we just immediately write the previous 2800 points to our raw buffer
    ############################################################################
    def updateTimeAndBuffer(self, device, pvname, timestamp, value):
        def padRawBufferWithNans(start, end):
            rtbsaUtils.padWithNans(self.rawBuffers[device], start, end)

        if "HSTBR" in pvname:
            self.timeStamps[device] = timestamp

            # value is the buffer because we're monitoring the HSTBR PV
            self.rawBuffers[device] = value

            # Reset the counter every time we reinitialize the plot
            self.counter[device] = 0

        else:
            if not self.timeStamps[device]:
                return

            rate = self.getRate()
            if rate < 1:
                return

            scalingFactor = 1.0 / rate
            elapsedPulses = round(
                (timestamp - self.timeStamps[device]) / scalingFactor)

            currIdx = int((timestamp / scalingFactor) % self.numPoints)

            if elapsedPulses <= 0:
                return

            # Pad the buffer with nans for missed pulses
            elif elapsedPulses > 1:

                # noinspection PyTypeChecker
                lastIdx = int(
                    (self.timeStamps[device] / scalingFactor) % self.numPoints)

                # Take care of wrap around
                if currIdx < lastIdx:
                    padRawBufferWithNans(lastIdx + 1, self.numPoints)
                    padRawBufferWithNans(0, currIdx)

                else:
                    padRawBufferWithNans(lastIdx + 1, currIdx)

            # Directly index into the raw buffer using the timestamp
            self.rawBuffers[device][currIdx] = value

            self.counter[device] += elapsedPulses
            self.timeStamps[device] = timestamp
            self.currIdx[device] = currIdx

    def clearPV(self, device):
        pv = self.pvObjects[device]
        if pv:
            pv.clear_callbacks()
            pv.disconnect()

    def adjustSynchronizedBuffers(self, syncByTime=False):
        numBadShots = self.populateSynchronizedBuffers(syncByTime)
        blength = 2800 - numBadShots

        # Make sure the buffer size doesn't exceed the desired number of points
        if self.numPoints < blength:
            self.synchronizedBuffers["A"] = \
                self.synchronizedBuffers["A"][:self.numPoints]

            self.synchronizedBuffers["B"] = \
                self.synchronizedBuffers["B"][:self.numPoints]

    # A spin loop that waits until the beam rate is at least 1Hz
    def waitForRate(self):

        start_time = time()
        gotStuckAndNeedToUpdateMessage = False

        # self.rate is a PV, such that .value is shorthand for .getval
        while self.ratePV.value < 1:
            # while self.ratePV.value < 2:
            #     # noinspection PyArgumentList
            QApplication.processEvents()
            #
            if time() - start_time > 0.5:
                gotStuckAndNeedToUpdateMessage = True
                self.printStatus("Waiting for beam rate to be at least 1Hz...",
                                 False)

        if gotStuckAndNeedToUpdateMessage:
            self.printStatus("Running", False)

        # return rtbsaUtils.rateDict[self.ratePV.value]
        return self.ratePV.value

    ############################################################################
    # Time 1 is when Device A started acquiring data, and Time 2 is when Device
    # B started acquiring data. Since they're not guaranteed to start
    # acquisition at the same time, one data buffer might be ahead of the other,
    # meaning that the intersection of the two buffers would not include the
    # first n elements of one and the last n elements of the other. See the
    # diagram below, where the dotted line represents the time axis (one buffer
    # is contained  by square brackets [], the other by curly braces {}, and the
    # times where each starts and ends is indicated right underneath).
    #
    #
    #          [           {                            ]           }
    # <----------------------------------------------------------------------> t
    #       t1_start    t2_start                     t1_end      t2_end
    #
    #
    # Note that both buffers are of the same size (2800) so that:
    # (t1_end - t1_start) = (t2_end - t2_start)
    #
    # From the diagram, we see that only the time between t2_start and t1_end
    # contains data from both buffers (t1_start to t2_start only contains data
    # from buffer 1, and t1_end to t2_end only contains data from buffer 2).
    # Using that, we can chop the beginning of buffer 1 and the end of buffer 2
    # so that we're only left with the overlapping region.
    #
    # In order to figure out how many points we need to chop from each buffer
    # (it's the same number for both since they're both the same size), we
    # multiply the time delta by the beam rate (yay dimensional analysis!):
    # seconds * (shots/second) = (number of shots)
    #
    # That whole rigmarole only applies to the initial population of the buffers
    # (where we're pulling the entire history buffer at once using the HSTBR
    # suffix). From then on, we're indexing into the raw buffers using the
    # pulse ID modulo 2800, so they're inherently synchronized
    ############################################################################
    def populateSynchronizedBuffers(self, syncByTime):
        def padSyncBufferWithNans(device, startIdx, endIdx):
            lag = endIdx - startIdx

            if lag > 20:
                print("Reinitializing buffers due to " + str(lag) +
                      " shot lag for device " + device)
                self.initializeBuffers()

            else:
                rtbsaUtils.padWithNans(self.synchronizedBuffers[device],
                                       startIdx + 1, endIdx + 1)

        def checkIndices(device, startIdx, endIdx):
            # Check for index wraparound
            if endIdx < startIdx:
                padSyncBufferWithNans(device, startIdx, self.numPoints - 1)
                padSyncBufferWithNans(device, 0, endIdx)

            else:
                padSyncBufferWithNans(device, startIdx, endIdx)

        if syncByTime:
            numBadShots = int(
                round((self.timeStamps["B"] - self.timeStamps["A"]) *
                      self.getRate()))

            startA, endA = rtbsaUtils.getIndices(numBadShots, 1)
            startB, endB = rtbsaUtils.getIndices(numBadShots, -1)

            self.synchronizedBuffers["A"] = self.rawBuffers["A"][startA:endA]
            self.synchronizedBuffers["B"] = self.rawBuffers["B"][startB:endB]

            return abs(numBadShots)

        else:

            self.synchronizedBuffers["A"] = self.rawBuffers["A"]
            self.synchronizedBuffers["B"] = self.rawBuffers["B"]

            # The timestamps and indices get updated by the callbacks, so we
            # store the values at the time of buffer-copying
            timeStampA = self.timeStamps["A"]
            timeStampB = self.timeStamps["B"]

            currIdxA = self.currIdx["A"]
            currIdxB = self.currIdx["B"]

            diff = timeStampA - timeStampB

            if diff > 0:
                checkIndices("A", currIdxB, currIdxA)

            elif diff < 0:
                checkIndices("B", currIdxA, currIdxB)

            return 0

    def genPlotAndSetTimer(self, genPlot, updateMethod):
        if self.abort:
            return

        try:
            genPlot()
        except UnboundLocalError:
            self.printStatus('No Data, Aborting Plotting Algorithm')
            return

        self.timer = QTimer(self)

        # Run updateMethod every updatetime milliseconds
        self.timer.singleShot(self.updateTime, updateMethod)

        self.printStatus('Running')

    # noinspection PyTypeChecker
    def genTimePlotA(self):
        newData = self.initializeData()

        if not newData.size:
            self.printStatus('Invalid PV? Unable to get data. Aborting.')
            self.ui.startButton.setEnabled(True)
            return

        data = newData[:self.numPoints]

        self.plotAttributes["curve"] = PlotCurveItem(data, pen=1)
        self.plot.addItem(self.plotAttributes["curve"])

        self.plotFit(arange(self.numPoints), data, self.devices["A"])

    ############################################################################
    # This is the main plotting function for "Plot A vs Time" that gets called
    # every self.updateTime seconds
    # noinspection PyTypeChecker
    ############################################################################
    def updateTimePlotA(self):

        if not self.checkPlotStatus():
            return

        xData, yData = self.filterTimePlotBuffer()

        if yData.size:
            self.plotAttributes["curve"].setData(yData)
            if self.ui.checkBoxAutoscale.isChecked():
                mx = max(yData)
                mn = min(yData)
                if mx - mn > .00001:
                    self.plot.setYRange(mn, mx)
                    self.plot.setXRange(0, len(yData))

            if self.ui.checkBoxShowAve.isChecked():
                rtbsaUtils.setPosAndText(self.text["avg"], mean(yData), 0,
                                         min(yData), 'AVG: ')

            if self.ui.checkBoxShowStdDev.isChecked():
                rtbsaUtils.setPosAndText(self.text["std"],
                                         std(yData), self.numPoints / 4,
                                         min(yData), 'STD: ')

            if self.ui.checkBoxCorrCoeff.isChecked():
                self.text["corr"].setText('')

            if self.ui.checkBoxLinFit.isChecked():
                self.text["slope"].setPos(self.numPoints / 2, min(yData))
                self.getLinearFit(xData, yData, True)

            elif self.ui.checkBoxPolyFit.isChecked():
                self.text["slope"].setPos(self.numPoints / 2, min(yData))
                self.getPolynomialFit(xData, yData, True)

        self.timer.singleShot(self.updateTime, self.updateTimePlotA)

    def checkPlotStatus(self):
        QApplication.processEvents()

        if self.abort:
            return False

        self.waitForRate()

        # kill switch to stop backgrounded, forgetten GUIs. Somewhere in the
        # ballpark of 20 minutes assuming 120Hz
        if self.counter["A"] > 150000:
            self.stop()
            self.printStatus("Stopping due to inactivity")

        return True

    def filterTimePlotBuffer(self):
        currIdx = self.currIdx["A"]
        choppedBuffer = self.rawBuffers["A"][:self.numPoints]

        # All this nonsense to make it scroll :P Thanks to Ben for the
        # inspiration!
        if currIdx > 0:
            choppedBuffer = concatenate(
                [choppedBuffer[currIdx:], choppedBuffer[:currIdx]])

        xData, yData = rtbsaUtils.filterBuffers(choppedBuffer,
                                                lambda x: ~isnan(x),
                                                arange(self.numPoints),
                                                choppedBuffer)

        if self.devices["A"] == "BLEN:LI24:886:BIMAX":
            xData, yData = rtbsaUtils.filterBuffers(
                yData, lambda x: x < rtbsaUtils.IPK_LIMIT, xData, yData)

        if self.ui.checkBoxStdDev.isChecked():
            stdDevFilterFunc = self.StdDevFilterFunc(mean(yData), std(yData))
            xData, yData = rtbsaUtils.filterBuffers(yData, stdDevFilterFunc,
                                                    xData, yData)
        return xData, yData

    def getLinearFit(self, xData, yData, updateExistingPlot):
        # noinspection PyTupleAssignmentBalance
        m, b = polyfit(xData, yData, 1)
        fitData = polyval([m, b], xData)

        self.text["slope"].setText('Slope: ' + str("{:.3e}".format(m)))

        if updateExistingPlot:
            self.plotAttributes["fit"].setData(xData, fitData)
        else:
            # noinspection PyTypeChecker
            self.plotAttributes["fit"] = PlotCurveItem(xData,
                                                       fitData,
                                                       'g-',
                                                       linewidth=1)

    def getPolynomialFit(self, xData, yData, updateExistingPlot):
        co = polyfit(xData, yData, self.fitOrder)
        pol = poly1d(co)
        xDataSorted = sorted(xData)
        fit = pol(xDataSorted)

        if updateExistingPlot:
            self.plotAttributes["parab"].setData(xDataSorted, fit)
        else:
            # noinspection PyTypeChecker
            self.plotAttributes["parab"] = PlotCurveItem(xDataSorted,
                                                         fit,
                                                         pen=3,
                                                         size=2)

        if self.fitOrder == 2:
            self.text["slope"].setText('Peak: ' + str(-co[1] / (2 * co[0])))

        elif self.fitOrder == 3:
            self.text["slope"].setText(
                str("{:.2e}".format(co[0])) + 'x^3' +
                str("+{:.2e}".format(co[1])) + 'x^2' +
                str("+{:.2e}".format(co[2])) + 'x' +
                str("+{:.2e}".format(co[3])))

    def genPlotAB(self):
        if self.ui.checkBoxStdDev.isChecked():
            self.plotCurveAndFit(self.filteredBuffers["A"],
                                 self.filteredBuffers["B"])
        else:
            self.plotCurveAndFit(self.synchronizedBuffers["A"],
                                 self.synchronizedBuffers["B"])

    def plotCurveAndFit(self, xData, yData):
        # noinspection PyTypeChecker
        self.plotAttributes["curve"] = ScatterPlotItem(xData,
                                                       yData,
                                                       pen=1,
                                                       symbol='x',
                                                       size=5)
        self.plot.addItem(self.plotAttributes["curve"])
        self.plotFit(xData, yData,
                     self.devices["B"] + ' vs. ' + self.devices["A"])

    def plotFit(self, xData, yData, title):
        self.plot.addItem(self.plotAttributes["curve"])
        self.plot.setTitle(title)

        # Fit line
        if self.ui.checkBoxLinFit.isChecked():
            self.getLinearFit(xData, yData, False)
            self.plot.addItem(self.plotAttributes["fit"])

        # Fit polynomial
        elif self.ui.checkBoxPolyFit.isChecked():
            self.ui.fitOrder.setDisabled(False)
            try:
                self.getPolynomialFit(xData, yData, False)
                self.plot.addItem(self.plotAttributes["parab"])
            except linalg.linalg.LinAlgError:
                print "Error getting polynomial fit"

    ############################################################################
    # This is the main plotting function for "Plot B vs A" that gets called
    # every self.updateTime milliseconds
    ############################################################################
    def updatePlotAB(self):
        if not self.checkPlotStatus():
            return

        QApplication.processEvents()

        self.adjustSynchronizedBuffers()
        self.filterNans()
        self.filterPeakCurrent()

        if self.ui.checkBoxStdDev.isChecked():
            self.filterStdDev()
            self.updateLabelsAndFit(self.filteredBuffers["A"],
                                    self.filteredBuffers["B"])
        else:
            self.updateLabelsAndFit(self.synchronizedBuffers["A"],
                                    self.synchronizedBuffers["B"])

        self.timer.singleShot(self.updateTime, self.updatePlotAB)

    def filterNans(self):
        def filterFunc(x):
            return ~isnan(x)

        self.filterData(self.synchronizedBuffers["A"], filterFunc, True)
        self.filterData(self.synchronizedBuffers["B"], filterFunc, True)

    # Need to filter out errant indices from both buffers to keep them
    # synchronized
    def filterData(self, dataBuffer, filterFunc, changeOriginal):
        bufferA, bufferB = rtbsaUtils.filterBuffers(
            dataBuffer, filterFunc, self.synchronizedBuffers["A"],
            self.synchronizedBuffers["B"])

        if changeOriginal:
            self.synchronizedBuffers["A"] = bufferA
            self.synchronizedBuffers["B"] = bufferB
        else:
            self.filteredBuffers["A"] = bufferA
            self.filteredBuffers["B"] = bufferB

    # This PV gets insane values, apparently
    def filterPeakCurrent(self):
        def filterFunc(x):
            return x < rtbsaUtils.IPK_LIMIT

        if self.devices["A"] == "BLEN:LI24:886:BIMAX":
            self.filterData(self.synchronizedBuffers["A"], filterFunc, True)
        if self.devices["B"] == "BLEN:LI24:886:BIMAX":
            self.filterData(self.synchronizedBuffers["B"], filterFunc, True)

    def filterStdDev(self):

        bufferA = self.synchronizedBuffers["A"]
        bufferB = self.synchronizedBuffers["B"]

        self.filterData(bufferA,
                        self.StdDevFilterFunc(mean(bufferA), std(bufferA)),
                        False)

        self.filterData(bufferB,
                        self.StdDevFilterFunc(mean(bufferB), std(bufferB)),
                        False)

    def StdDevFilterFunc(self, average, stdDev):
        return lambda x: abs(x - average) < self.stdDevstoKeep * stdDev

    # noinspection PyTypeChecker
    def updateLabelsAndFit(self, bufferA, bufferB):
        self.plotAttributes["curve"].setData(bufferA, bufferB)

        try:
            if self.ui.checkBoxAutoscale.isChecked():
                self.setPlotRanges(bufferA, bufferB)

            minBufferA = nanmin(bufferA)
            minBufferB = nanmin(bufferB)
            maxBufferA = nanmax(bufferA)
            maxBufferB = nanmax(bufferB)

            if self.ui.checkBoxShowAve.isChecked():
                rtbsaUtils.setPosAndText(self.text["avg"], nanmean(bufferB),
                                         minBufferA, minBufferB, 'AVG: ')

            if self.ui.checkBoxShowStdDev.isChecked():
                xPos = (minBufferA + (minBufferA + maxBufferA) / 2) / 2

                rtbsaUtils.setPosAndText(self.text["std"], nanstd(bufferB),
                                         xPos, minBufferB, 'STD: ')

            if self.ui.checkBoxCorrCoeff.isChecked():
                correlation = corrcoef(bufferA, bufferB)
                rtbsaUtils.setPosAndText(self.text["corr"],
                                         correlation.item(1), minBufferA,
                                         maxBufferB, "Corr. Coefficient: ")

            if self.ui.checkBoxLinFit.isChecked():
                self.text["slope"].setPos((minBufferA + maxBufferA) / 2,
                                          minBufferB)
                self.getLinearFit(bufferA, bufferB, True)

            elif self.ui.checkBoxPolyFit.isChecked():
                self.text["slope"].setPos((minBufferA + maxBufferA) / 2,
                                          minBufferB)
                self.getPolynomialFit(bufferA, bufferB, True)

        except ValueError:
            print "Error updating plot range"

    def setPlotRanges(self, bufferA, bufferB):
        mx = nanmax(bufferB)
        mn = nanmin(bufferB)

        if mn != mx:
            self.plot.setYRange(mn, mx)

        mx = nanmax(bufferA)
        mn = nanmin(bufferA)

        if mn != mx:
            self.plot.setXRange(mn, mx)

    def InitializeFFTPlot(self):
        self.genPlotFFT(self.initializeData(), False)

    # TODO I have no idea what's happening here
    def genPlotFFT(self, newdata, updateExistingPlot):

        if not newdata.size:
            return None

        newdata = newdata[:self.numPoints]

        nans, x = isnan(newdata), lambda z: z.nonzero()[0]
        # interpolate nans
        newdata[nans] = interp(x(nans), x(~nans), newdata[~nans])
        # remove DC component
        newdata = newdata - mean(newdata)

        newdata = concatenate([newdata, zeros(self.numPoints * 2)])

        ps = abs(fft.fft(newdata)) / newdata.size

        self.waitForRate()
        frequencies = fft.fftfreq(newdata.size, 1.0 / self.getRate())
        keep = (frequencies >= 0)
        ps = ps[keep]
        frequencies = frequencies[keep]
        idx = argsort(frequencies)

        if updateExistingPlot:
            self.plotAttributes["curve"].setData(x=frequencies[idx], y=ps[idx])
        else:
            # noinspection PyTypeChecker
            self.plotAttributes["curve"] = PlotCurveItem(x=frequencies[idx],
                                                         y=ps[idx],
                                                         pen=1)

        self.plot.addItem(self.plotAttributes["curve"])
        self.plot.setTitle(self.devices["A"])
        self.plotAttributes["frequencies"] = frequencies

        return ps

    # noinspection PyTypeChecker
    def cleanPlot(self):
        self.plot.clear()

        self.text["avg"] = TextItem('', color=(200, 200, 250), anchor=(0, 1))
        self.text["std"] = TextItem('', color=(200, 200, 250), anchor=(0, 1))
        self.text["slope"] = TextItem('', color=(200, 200, 250), anchor=(0, 1))
        self.text["corr"] = TextItem('', color=(200, 200, 250), anchor=(0, 1))

        plotLabels = [
            self.text["avg"], self.text["std"], self.text["slope"],
            self.text["corr"]
        ]

        for plotLabel in plotLabels:
            self.plot.addItem(plotLabel)

    def initializeData(self):
        self.printStatus("Initializing " + self.devices["A"] + " buffer...",
                         True)

        if self.ui.dropdownButtonA.isChecked():
            self.devices["A"] = str(self.ui.dropdownA.currentText())

        elif self.ui.searchButtonA.isChecked():
            pv = str(self.ui.searchInputA.text()).strip()
            if pv and pv in self.bsapvs:
                self.devices["A"] = pv
            else:
                return None
        else:
            return None

        # Initializing our data by putting a callback on the history buffer PV
        self.clearAndUpdateCallback("A", "HSTBR", self.callbackA,
                                    self.devices["A"], True)

        while (not self.timeStamps["A"]) and not self.abort:
            QApplication.processEvents()

        # Removing that callback and manually appending new values to our local
        # data buffer using the usual PV
        # TODO ask Ahmed what the BR is for
        self.clearAndUpdateCallback("A", "BR", self.callbackA,
                                    self.devices["A"])

        # This was populated in the callback function
        return self.rawBuffers["A"]

    ############################################################################
    # This is the main plotting function for "Plot A FFT" that gets called
    # every self.updateTime seconds
    ############################################################################
    def updatePlotFFT(self):
        if not self.checkPlotStatus():
            return

        ps = self.genPlotFFT(self.rawBuffers["A"], True)

        if self.ui.checkBoxAutoscale.isChecked():
            mx = max(ps)
            mn = min(ps)
            if mx - mn > .00001:
                frequencies = self.plotAttributes["frequencies"]
                self.plot.setYRange(mn, mx)
                # noinspection PyTypeChecker
                self.plot.setXRange(min(frequencies), max(frequencies))

        self.timer.singleShot(self.updateTime, self.updatePlotFFT)

    def AvsTClick(self):
        if not self.ui.checkBoxAvsT.isChecked():
            pass
        else:
            self.ui.checkBoxBvsA.setChecked(False)
            self.ui.checkBoxFFT.setChecked(False)
            self.AvsBClick()

    def AvsBClick(self):
        if not self.ui.checkBoxBvsA.isChecked():
            self.ui.groupBoxB.setDisabled(True)
            self.ui.searchButtonB.setChecked(False)
            self.ui.searchButtonB.setDisabled(True)
            self.ui.searchInputB.setDisabled(True)
            self.ui.dropdownB.setDisabled(True)
            self.ui.dropdownButtonB.setChecked(False)
            self.ui.dropdownButtonB.setDisabled(True)
        else:
            self.ui.checkBoxAvsT.setChecked(False)
            self.ui.checkBoxFFT.setChecked(False)
            self.AvsTClick()
            self.ui.groupBoxB.setDisabled(False)
            self.ui.bsaListB.setDisabled(True)
            self.ui.searchButtonB.setDisabled(False)
            self.ui.searchInputB.setDisabled(True)
            self.ui.dropdownButtonB.setDisabled(False)
            self.ui.dropdownButtonB.setChecked(True)
            self.ui.dropdownB.setDisabled(False)

        self.stop()
        self.timer.singleShot(250, self.initializePlot)

    def AFFTClick(self):
        if not self.ui.checkBoxFFT.isChecked():
            pass
        else:
            self.ui.checkBoxBvsA.setChecked(False)
            self.ui.checkBoxAvsT.setChecked(False)
            self.AvsBClick()

    def avg_click(self):
        if not self.ui.checkBoxShowAve.isChecked():
            self.text["avg"].setText('')

    def std_click(self):
        if not self.ui.checkBoxShowStdDev.isChecked():
            self.text["std"].setText('')

    def corr_click(self):
        if not self.ui.checkBoxCorrCoeff.isChecked():
            self.text["corr"].setText('')

    def enter_1_click(self):
        if self.ui.searchButtonA.isChecked():
            self.ui.searchInputA.setDisabled(False)
            self.ui.bsaListA.setDisabled(False)
            self.ui.dropdownButtonA.setChecked(False)
            self.ui.dropdownA.setDisabled(True)
        else:
            self.ui.searchInputA.setDisabled(True)

    def enter_2_click(self):
        if self.ui.searchButtonB.isChecked():
            self.ui.searchInputB.setDisabled(False)
            self.ui.bsaListB.setDisabled(False)
            self.ui.dropdownButtonB.setChecked(False)
            self.ui.dropdownB.setDisabled(True)
        else:
            self.ui.searchInputB.setDisabled(True)

    def common_1_click(self):
        if self.ui.dropdownButtonA.isChecked():
            self.ui.dropdownA.setEnabled(True)
            self.ui.searchButtonA.setChecked(False)
            self.ui.searchInputA.setDisabled(True)
            self.ui.bsaListA.setDisabled(True)
        else:
            self.ui.dropdownA.setEnabled(False)
        self.inputActivated()

    def inputActivated(self):
        if not self.abort:
            self.stop()
            self.timer.singleShot(250, self.initializePlot)

    def common_2_click(self):
        if self.ui.dropdownButtonB.isChecked():
            self.ui.dropdownB.setEnabled(True)
            self.ui.searchButtonB.setChecked(False)
            self.ui.searchInputB.setDisabled(True)
            self.ui.bsaListB.setDisabled(True)
        else:
            self.ui.dropdownB.setEnabled(False)
        self.inputActivated()

    def line_click(self):
        self.ui.checkBoxPolyFit.setChecked(False)
        self.ui.fitOrder.setDisabled(True)
        self.ui.labelFitOrder.setDisabled(True)
        self.reinitialize_plot()

    def fitOrderActivated(self):
        try:
            self.fitOrder = int(self.ui.fitOrder.text())
        except ValueError:
            self.statusBar().showMessage('Enter an integer, 1-10', 6000)
            return

        if self.fitOrder > 10 or self.fitOrder < 1:
            self.statusBar().showMessage(
                'Really?  That is going to be useful' +
                ' to you?  The (already ridiculous)' +
                ' range is 1-10.  Hope you win a ' + 'nobel prize jackass.',
                6000)
            self.ui.fitOrder.setText('2')
            self.fitOrder = 2

        if self.fitOrder != 2:
            try:
                self.text["slope"].setText('')
            except AttributeError:
                pass

    def parab_click(self):
        self.ui.checkBoxLinFit.setChecked(False)

        if not self.ui.checkBoxPolyFit.isChecked():
            self.ui.fitOrder.setDisabled(True)
            self.ui.labelFitOrder.setDisabled(True)
        else:
            self.ui.fitOrder.setEnabled(True)
            self.ui.labelFitOrder.setEnabled(True)

        self.reinitialize_plot()

    # This is a mess, but it works (used if user changes number points,
    # fit type etc.)
    def reinitialize_plot(self):
        self.cleanPlot()

        # Setup for single PV plotting
        if self.ui.checkBoxAvsT.isChecked():
            self.genTimePlotA()

        elif self.ui.checkBoxBvsA.isChecked():
            self.genPlotAB()
        else:
            self.genPlotFFT(self.synchronizedBuffers["A"], False)

    def logbook(self):
        rtbsaUtils.logbook('Python Real-Time BSA', 'BSA Data',
                           str(self.numPoints) + ' points', self.plot.plotItem)
        self.statusBar().showMessage('Sent to LCLS Physics Logbook!', 10000)

    def MCCLog(self):
        rtbsaUtils.MCCLog('/tmp/RTBSA.png', '/tmp/RTBSA.ps',
                          self.plot.plotItem)

    def clearCallbacks(self, device):
        if self.pvObjects[device]:
            self.pvObjects[device].clear_callbacks()
            self.pvObjects[device].disconnect()

    def stop(self):
        self.clearCallbacks("A")

        if self.pvObjects["B"]:
            self.clearCallbacks("B")

        self.abort = True
        self.statusBar().showMessage('Stopped')
        self.ui.startButton.setDisabled(False)
        QApplication.processEvents()

    def create_menu(self):

        load_file_action = self.create_action("&Save plot",
                                              shortcut="Ctrl+S",
                                              slot=self.save_plot,
                                              tip="Save the plot")

        quit_action = self.create_action("&Quit",
                                         slot=self.close,
                                         shortcut="Ctrl+Q",
                                         tip="Close the application")

        rtbsaUtils.add_actions(self.file_menu,
                               (load_file_action, None, quit_action))

        about_action = self.create_action("&About",
                                          shortcut='F1',
                                          slot=self.on_about,
                                          tip='About')

        rtbsaUtils.add_actions(self.help_menu, (about_action, ))

    def create_action(self,
                      text,
                      slot=None,
                      shortcut=None,
                      icon=None,
                      tip=None,
                      checkable=False,
                      signal="triggered()"):

        action = QAction(text, self)

        if icon is not None:
            action.setIcon(QIcon(":/%s.png" % icon))
        if shortcut is not None:
            action.setShortcut(shortcut)
        if tip is not None:
            action.setToolTip(tip)
            action.setStatusTip(tip)
        if slot is not None:
            self.connect(action, SIGNAL(signal), slot)
        if checkable:
            action.setCheckable(True)
        return action

    def save_plot(self):
        file_choices = "PNG (*.png)|*.png"
        # noinspection PyTypeChecker,PyCallByClass
        filePath = unicode(
            QFileDialog.getSaveFileName(self, 'Save file', '', file_choices))
        if filePath:
            self.ui.widgetPlot.canvas.print_figure(filePath, dpi=100)
            self.statusBar().showMessage('Saved to %s' % filePath, 2000)

    def on_about(self):
        msg = (
            "Can you read this?  If so, congratulations. You are a magical, " +
            "marvelous troll.")
        # noinspection PyCallByClass
        QMessageBox.about(self, "About", msg.strip())
コード例 #23
0
class AppWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        self.graph_types = [Lattice_2d, Triangles_2d, Honeycomb_2d, Lattice_3d]
        self.graph_names = [
            "2D-Grid", "2D-Triangles", "2D-Honeycomb", "3D-Grid"
        ]

        self.setupLayout()
        self.setSettings()

    def setSettings(self):
        self.graph_type_combobox.setCurrentIndex(0)
        self.p_slider.setValue(100)
        self.N_slider.setValue(5)
        self.refresh_edges_checkbox.setCheckState(Qt.Checked)

    def setupLayout(self):
        self.layout = QHBoxLayout(self)
        self.splitter = QSplitter(Qt.Horizontal)

        self.settingswidget = QWidget(self)
        self.settingswidget.setMaximumWidth(400)
        self.settingslayout = QVBoxLayout()

        self.percolationWidget = PercolationWidget()

        self.graph_type_combobox = QComboBox(self)
        self.graph_type_combobox.addItems(self.graph_names)
        self.graph_type_combobox.currentIndexChanged.connect(
            self.handleGraphTypeChanged)
        self.graph_type_combobox.setFocusPolicy(Qt.NoFocus)
        self.settingslayout.addWidget(self.graph_type_combobox)

        self.p_slider_layout = QHBoxLayout()
        self.settingslayout.addLayout(self.p_slider_layout)

        self.p_slider_layout.addWidget(QLabel("Set p value: ", self))

        self.p_slider_label = QLabel(self)

        self.p_slider = QSlider(Qt.Horizontal, self)
        self.p_slider.valueChanged.connect(self.handlePSliderChange)

        self.p_slider_layout.addWidget(self.p_slider)
        self.p_slider_layout.addWidget(self.p_slider_label)

        self.N_slider_layout = QHBoxLayout()
        self.settingslayout.addLayout(self.N_slider_layout)

        self.N_slider_layout.addWidget(QLabel("Set size (N): ", self))

        self.N_slider_label = QLabel(self)

        self.N_slider = QSlider(Qt.Horizontal, self)
        self.N_slider.valueChanged.connect(self.handleNSliderChange)

        self.N_slider_layout.addWidget(self.N_slider)
        self.N_slider_layout.addWidget(self.N_slider_label)

        # wether to refresh edges each time or keep edges to add to/remove from
        self.refresh_edges_checkbox = QCheckBox(
            "Refresh Edges instead of Adding/Removing", self)
        self.refresh_edges_checkbox.stateChanged.connect(
            self.handleRefreshCheckboxChange)

        self.settingslayout.addWidget(self.refresh_edges_checkbox)

        self.settingslayout.addSpacerItem(
            QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding))

        self.plot_widget = PlotWidget(name="clustersize by p")
        self.settingslayout.addWidget(self.plot_widget)
        self.plot_widget.setLabel('left', 'maximum cluster size', units='%')
        self.plot_widget.setLabel('bottom', 'p', units='')
        self.plot_widget.setXRange(0, 1)
        self.plot_widget.setYRange(0, 1)
        self.plot = ScatterPlotItem()
        self.plot_widget.addItem(self.plot)

        self.plot_clear_button = QPushButton("Clear plot")
        self.plot_clear_button.clicked.connect(self.handlePlotClearButton)
        self.settingslayout.addWidget(self.plot_clear_button)

        self.settingswidget.setLayout(self.settingslayout)
        self.settingswidget.setMinimumSize(50, 50)

        self.splitter.addWidget(self.settingswidget)
        self.splitter.addWidget(self.percolationWidget)

        self.layout.addWidget(self.splitter)

        self.percolationWidget.graphUpdated.connect(self.handleGraphUpdated)

        self.setWindowTitle('Percolation Model')

        self.setFocus()

    def handleGraphTypeChanged(self, index):
        if (self.graph_types[index].dim == 3):
            self.N_slider.setValue(10)
        self.graph = self.graph_types[index](self.N_slider.value())
        self.percolationWidget.setGraph(self.graph)
        self.setFocus()

    def handlePSliderChange(self, value):
        self.percolationWidget.setPValue(value)
        self.p_slider_label.setText(str(value) + " %")

    def handleNSliderChange(self, value):
        self.graph = self.graph_types[self.graph_type_combobox.currentIndex()](
            value)
        self.percolationWidget.setGraph(self.graph)
        self.N_slider_label.setText(str(value))

    def handleRefreshCheckboxChange(self, value):
        self.percolationWidget.setRefresh(value == Qt.Checked)

    def handleGraphUpdated(self, p, clustersize):
        self.plot.addPoints(x=[p], y=[clustersize])

    def handlePlotClearButton(self):
        self.plot = ScatterPlotItem()
        self.plot_widget.clear()
        self.plot_widget.addItem(self.plot)
        self.plot_widget.update()

    def keyPressEvent(self, event):
        if event.key() in [
                Qt.Key_W, Qt.Key_A, Qt.Key_S, Qt.Key_D, Qt.Key_Q, Qt.Key_E,
                Qt.Key_Plus, Qt.Key_Minus
        ]:
            self.percolationWidget.graphwidget.keyPressEvent(event)
        elif event.key() == Qt.Key_Tab:
            self.setFocus()
        else:
            QWidget.keyPressEvent(self, event)
コード例 #24
0
ファイル: ui_main.py プロジェクト: DrMikeG/PiBat
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(600, 400)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.horizontalLayout = QtGui.QHBoxLayout(self.centralwidget)
        self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
        #self.pbLevel = QtGui.QProgressBar(self.centralwidget)
        #self.pbLevel.setMaximum(1000)
        #self.pbLevel.setProperty("value", 123)
        #self.pbLevel.setTextVisible(False)
        #self.pbLevel.setOrientation(QtCore.Qt.Vertical)
        #self.pbLevel.setObjectName(_fromUtf8("pbLevel"))
        #self.horizontalLayout.addWidget(self.pbLevel)
        self.frame = QtGui.QFrame(self.centralwidget)
        self.frame.setFrameShape(QtGui.QFrame.NoFrame)
        self.frame.setFrameShadow(QtGui.QFrame.Plain)
        self.frame.setObjectName(_fromUtf8("frame"))
        self.verticalLayout = QtGui.QVBoxLayout(self.frame)
        self.verticalLayout.setMargin(0)
        self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
        #self.label = QtGui.QLabel(self.frame)
        #self.label.setObjectName(_fromUtf8("label"))
        #self.verticalLayout.addWidget(self.label)
        self.grFFT = PlotWidget(self.frame)
        self.grFFT.setObjectName(_fromUtf8("grFFT"))
        

        self.grFFT.img = pg.ImageItem()
        self.grFFT.addItem(self.grFFT.img)
        #CHUNKSZ = 500
        #FS = 192000
        #self.grFFT.img_array = np.zeros((1000, CHUNKSZ/2+1))
        fftImgHeight = 512
        self.grFFT.img_array = np.zeros((1000, fftImgHeight))

        # bipolar colormap
        #pos = np.array([0., 1., 0.5, 0.25, 0.75])
        #color = np.array([[0,255,255,255], [255,255,0,255], [0,0,0,255],(0, 0, 255, 255), (255, 0, 0, 255)], dtype=np.ubyte)
        #cmap = pg.ColorMap(pos, color)
        #lut = cmap.getLookupTable(0.0, 1.0, 256)

        #pos2 = np.array([0.0, 0.2, 0.4, 0.6, 0.8])
        #color2 = np.array([[75,64,128,255],[64,107,128,255],[64,128,96,255],[85,128,64,255],[128,117,64,255],[128,64,64,255]],dtype=np.ubyte)
        pos2 = np.array([0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0])
        color2 = np.array([[51,000,51,255],[127,000,255,255],[000,000,255,255],[000,128,255,255],[000,255,255,255],[000,255,128,255],[000,255,000,255],[128,255,000,255],[255,255,000,255],[255,128,000,255],[255,000,000,255]],dtype=np.ubyte)
        cmap2 = pg.ColorMap(pos2,color2)
        lut = cmap2.getLookupTable(0.0, 1.0, 512) # get lookup table from 0 to 1 (512 pts)


        # set colormap
        self.grFFT.img.setLookupTable(lut)
        self.grFFT.img.setLevels([0,1])

        # setup the correct scaling for y-axis
        #freq = np.arange((CHUNKSZ/2)+1)/(float(CHUNKSZ)/FS)
        #yscale = 1.0/(self.grFFT.img_array.shape[1]/freq[-1])
        #self.grFFT.img.scale((1./FS)*CHUNKSZ, yscale)
        
        self.verticalLayout.addWidget(self.grFFT)
        #self.label_2 = QtGui.QLabel(self.frame)
        #self.label_2.setObjectName(_fromUtf8("label_2"))
        #self.verticalLayout.addWidget(self.label_2)
        
        #self.grPCM = PlotWidget(self.frame)
        #self.grPCM.setObjectName(_fromUtf8("grPCM"))
        #self.verticalLayout.addWidget(self.grPCM)
        self.horizontalLayout.addWidget(self.frame)
        MainWindow.setCentralWidget(self.centralwidget)

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

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
コード例 #25
0
ファイル: qGraph.py プロジェクト: shanet/Osprey
class QGraph(QWidget):
  def __init__(self, config, parent=None, **kwargs):
    QWidget.__init__(self, parent)
    self.startTime = None
    self.numDataPoints = 0

    self.datasets = {}

    for display in config['displays']:
      self.datasets[display['field']] = self.createDatasetForDisplay(display)

    self.graph = PlotWidget(title=config['title'], labels=config['labels'])

    # Only add a legend to the graph if there is more than one dataset displayed on it
    if len(self.datasets) > 1:
      self.graph.addLegend()

    # Show grid lines
    self.graph.showGrid(x=True, y=True)

    for _, dataset in self.datasets.items():
      self.graph.addItem(dataset['plotData'])

    vbox = QVBoxLayout()
    vbox.addWidget(self.graph)
    self.setLayout(vbox)

  def createDatasetForDisplay(self, display):
    plotData = PlotDataItem(name=display['label'])

    if 'color' in display:
      plotData.setPen(mkPen({'color': display['color']}))

    return {
      'plotData': plotData,
      'points': numpy.zeros((constants.NUMPY_ARRAY_SIZE, 2)),
    }

  def updateDataset(self, dataset):
    time = self.getAxisTime(dataset)

    # Skip updating if no time is available
    if not time:
      return

    for field, _ in self.datasets.items():
      self.updatePoints(time, field, dataset)
      self.updateGraphs(field, dataset)

    self.numDataPoints += 1

  def updatePoints(self, time, field, dataset):
    for key, data in dataset.items():
      # Only plot float values
      if field == key and isinstance(data, float):
        self.datasets[field]['points'][self.numDataPoints] = (time, data)
        return


  def getAxisTime(self, dataset):
    # Use the first dataset as the start time
    if not self.startTime and dataset['delta']:
      self.startTime = dataset['delta']

    if dataset['delta']:
      return (dataset['delta'] - self.startTime)
    else:
      return None

  def updateGraphs(self, field, dataset):
    for data in dataset.items():
      if field in dataset:
        # We don't want to graph the empty values in the points array so only
        # give the plot data the points up to the current number of data points
        points = self.datasets[field]['points']
        self.datasets[field]['plotData'].setData(points[0:self.numDataPoints])
コード例 #26
0
class widget_mfi_lon_plot(QWidget):

    #-----------------------------------------------------------------------
    # DEFINE THE INITIALIZATION FUNCTION.
    #-----------------------------------------------------------------------

    def __init__(self, core):

        # Inherit all attributes of an instance of "QWidget".

        super(widget_mfi_lon_plot, self).__init__()

        # Store the Janus core.

        self.core = core

        # Prepare to respond to signals received from the core.

        self.connect(self.core, SIGNAL('janus_rset'), self.resp_rset)
        self.connect(self.core, SIGNAL('janus_chng_mfi'), self.resp_chng_mfi)

        # Initialize this widget's instance of "PlotWidget", which will
        # contain the plot of MFI magnetic field data.

        # Note.  The "QGridLayout" object given to this widget as its
        #        layout is essentially a dummy.  I could have just had
        #        this class inherit "PlotWidget", but I think that this
        #        gives me a bit more control (and a similar structure
        #        "janus_widget_fc_cup").

        self.setLayout(QGridLayout())

        self.plt = PlotWidget()
        self.layout().addWidget(self.plt)

        self.layout().setContentsMargins(0, 0, 0, 0)

        # Extract the individual elements of the "PlotWidget" object
        # (e.g., it's axes) for more convenient access later.

        self.vbx = self.plt.getViewBox()

        self.axs_x = self.plt.getAxis('bottom')
        self.axs_y = self.plt.getAxis('left')

        self.ptm = self.plt.getPlotItem()

        # Initialize and store the pens and fonts.

        self.pen_vbx = mkPen(color='k')
        self.pen_crv_lon = mkPen(color='#FFD700')

        self.fnt = self.core.app.font()

        # Configure the plot: disable automatic adjustments and
        # adjustments made by the user, change the background and
        # foreground colors, enable grid lines for both axes, label the
        # axes, adjust the tick font size, adjust the "AxisItem" sizes,
        # and add a margin around the entire plot.

        self.plt.disableAutoRange()
        self.plt.setMouseEnabled(False, False)
        self.plt.setMenuEnabled(False)
        self.plt.hideButtons()

        self.plt.setBackground('w')
        setConfigOption('foreground', 'k')

        #####self.plt.showGrid( True, True )

        labelStyle = {'color': 'k'}
        self.axs_x.setLabel('Time [s]', **labelStyle)
        self.axs_y.setLabel('Azim. [deg]', **labelStyle)

        self.axs_x.label.setFont(self.fnt)
        self.axs_y.label.setFont(self.fnt)

        self.axs_x.setTickFont(self.fnt)
        self.axs_y.setTickFont(self.fnt)

        self.axs_x.setHeight(35)
        self.axs_y.setWidth(40)

        self.vbx.border = self.pen_vbx

        self.ptm.setContentsMargins(5, 5, 5, 5)

        # Initialize the curves that will be added to this plot.

        self.crv_lon = None

        # Populate this plot and adjust it's settings.

        self.make_plt()

    #-----------------------------------------------------------------------
    # DEFINE THE FUNCTION FOR POPULATING THE PLOT.
    #-----------------------------------------------------------------------

    def make_plt(self):

        # Reset the plot (i.e., remove all plot elements).

        self.rset_plt()

        # Establish the ranges of its time and magnetic field values.
        # If the core contains no data or only a single datum,
        # improvise (for the purpose of later establishing axis limits).

        if (self.core.n_mfi >= 1):

            # Establish the domain of the plot.

            t_min = min(amin(self.core.mfi_s), 0.)
            t_max = max(amax(self.core.mfi_s), self.core.fc_spec['dur'])

            # Establish the range of the plot.  As part of this,
            # ensure that the range satisfies a minimum size and has
            # sufficient padding.

            ang_max = max(self.core.mfi_b_lon)
            ang_min = min(self.core.mfi_b_lon)

            ang_max = 5. + ang_max
            ang_min = -5. + ang_min

            d_t_0 = t_max - t_min

            d_t = max(1.5 + d_t_0, 3.)

            t_max = t_min + d_t

        else:

            t_min = 0.001
            t_max = 3.500

            ang_min = -360
            ang_max = 360

        # Set the range of the axis of each plot.

        self.plt.setXRange(t_min, t_max, padding=0.0)
        self.plt.setYRange(ang_min, ang_max, padding=0.0)

        # If the core contains no Wind/MFI magnetic field data, return.

        if (self.core.n_mfi <= 0):
            return

        # Generate and display each curve for the plot.

        self.crv_lon = PlotDataItem(self.core.mfi_s,
                                    self.core.mfi_b_lon,
                                    pen=self.pen_crv_lon)

        self.plt.addItem(self.crv_lon)

    #-----------------------------------------------------------------------
    # DEFINE THE FUNCTION FOR RESETTING THIS PLOT (CLEARING ALL ELEMENTS).
    #-----------------------------------------------------------------------

    def rset_plt(self):

        # Hide and remove each of this plot's elements.

        if (self.crv_lon is not None):
            self.plt.removeItem(self.crv_lon)

        # Permanently delete this plot's elements by setting each of the
        # variables that store them to "None".

        self.crv_lon = None

    #-----------------------------------------------------------------------
    # DEFINE THE FUNCTION FOR RESPONDING TO THE "rset" SIGNAL.
    #-----------------------------------------------------------------------

    def resp_rset(self):

        # Reset the plot.

        self.rset_plt()

    #-----------------------------------------------------------------------
    # DEFINE THE FUNCTION FOR RESPONDING TO THE "chng_mfi" SIGNAL.
    #-----------------------------------------------------------------------

    def resp_chng_mfi(self):

        # Regenerate the plot.

        self.make_plt()
コード例 #27
0
class Plot(QObject, Object):
    """Generic widget to plot data series. The data series have to be added
    first, then one may add plot items using two them as x and y values. The
    series will be automatically updated when the master attribute fires a
    value_changed signal or based on an internal update timer. This master
    series has to be defined while adding it.
    
    .. todo:: Currently only setting both series of a plot item to the same,
        fixed length works. Find a better handling for this.
    """
    TYPE_STATIC = 0
    TYPE_TIME = 1
    TYPE_SCALAR = 2
    TYPE_SPECTRUM = 3

    ROLE_SLAVE = 0
    ROLE_MASTER = 1

    def __init__(self, parent=None):
        """Construct a new Plot instance.
        
        :param parent: Optional, but needed for painting.
        :type parent: QGraphicsItem
        """
        QObject.__init__(self)
        Object.__init__(self)
        self.parent = parent
        self.lines = {}
        self.items = {}  #plot items
        self.data = {}  #data series to the plot items
        self.master = None  #id of the data series which triggers the update
        self.x_range = -1  #id of the data series which range defines the plot range
        self.mutex = QMutex()
        self.update_timer = QTimer(self)
        self.update_timer_start = None
        self.setup_ui()

    def setup_ui(self):
        """Setup the internal widget object. Called by :func:`__init__()`."""
        self.widget = PlotWidget(self.parent)
        self.widget.setBackgroundBrush(QBrush(Qt.NoBrush))
        count = len(self.janus.widgets["mainwindow"].findChildren(PlotWidget))
        self.widget.setObjectName("plotWidgetPlot{0}".format(count))
        self.widget.getAxis("bottom").setPen(QPen(Qt.black))
        self.widget.getAxis("left").setPen(QPen(Qt.black))

    def update_values(self, attribute=None):
        """Update all data of TYPE_TIME, TYPE_SCALAR, TYPE_SPECTRUM and plot it.

        This method is connected to either the the value_changed signal of the
        device instance that the master attribute belongs to or the internal
        update_timer if the master is of TYPE_TIME. 

        :param attribute: Name of the master attribute
            which triggered the update or None if master is of TYPE_TIME.
        :type attribute: str|None
        """
        self.mutex.lock()
        if not ((attribute is None and \
                self.data[self.master]["data_type"] == Plot.TYPE_TIME) or \
                (attribute == self.data[self.master]["name"] and \
                self.data[self.master]["data_type"] in \
                [Plot.TYPE_SCALAR, Plot.TYPE_SPECTRUM])):
            self.mutex.unlock()
            return
        if self.update_timer_start is not None:
            time_stamp = time.time() - self.update_timer_start
        update = len(self.items) * [False]
        #retrieve new data and cycle the buffer if max_length is reached
        for i in range(len(self.data)):
            if self.data[i]["data_type"] == Plot.TYPE_TIME:
                if self.data[i]["data"].shape[0] > self.data[i]["max_length"]:
                    self.data[i]["data"].resize(self.data[i]["max_length"])
                if self.data[i]["data"].shape[0] == self.data[i]["max_length"]:
                    self.data[i]["data"] = numpy.concatenate( \
                            (self.data[i]["data"][1:], self.data[i]["data"][:1]))
                    self.data[i]["data"][-1] = time_stamp
                else:
                    numpy.concatenate(self.data[i]["data"], time_stamp)
            elif self.data[i]["data_type"] == Plot.TYPE_SCALAR:
                if self.data[i]["data"].shape[0] > self.data[i]["max_length"]:
                    self.data[i]["data"].resize(self.data[i]["max_length"])
                if self.data[i]["data"].shape[0] == self.data[i]["max_length"]:
                    self.data[i]["data"] = numpy.concatenate( \
                            (self.data[i]["data"][1:], self.data[i]["data"][:1]))
                    self.data[i]["data"][-1] = self.data[i]["getter"](
                        refresh=True)
                else:
                    numpy.concatenate(self.data[i]["data"], \
                            self.data[i]["getter"](refresh=True))
            elif self.data[i]["data_type"] == Plot.TYPE_SPECTRUM:
                self.data[i]["data"] = numpy.ndarray(
                    self.data[i]["getter"](refresh=True))
                if self.data[i]["data"].shape[0] >= self.data[i]["max_length"] or \
                        self.data[i]["data"].shape[0] < self.data[i]["min_length"]:
                    self.data[i]["data"].resize(self.data[i]["max_length"])
            else:
                continue
            for item in self.data[i]["items"]:
                update[item] = True
        #set view boundaries if tie_x_range is set to a dataset
        if self.x_range > -1:
            if self.data[self.x_range]["data_type"] == Plot.TYPE_TIME:
                self.widget.setLimits( \
                        xMin=self.data[self.x_range]["data"][1], \
                        xMax=self.data[self.x_range]["data"][-1])
            else:
                self.widget.setLimits( \
                        xMin=numpy.amin(self.data[self.x_range]["data"]), \
                        xMax=numpy.amax(self.data[self.x_range]["data"]))
        #replot items
        for i in range(len(self.items)):
            if update[i]:
                self.items[i]["plot"].setData( \
                        self.data[self.items[i]["x"]]["data"], \
                        self.data[self.items[i]["y"]]["data"])
        self.mutex.unlock()

    def add_plot_data(self, i, data=None, attr=None, data_type=TYPE_STATIC, \
                role=ROLE_SLAVE, interval=1.0, \
                min_length=0, length=-1, max_length=-1):
        """Add a data series to the plot.
        
        :param i: Id of the data series. Should be ascending natural numbers 
            from 0 up.
        :type i: int
        :param data: Initial series of values. May be omited if not of
            TYPE_STATIC.
        :type data: numpy.ndarray|None
        :param attr: Reference to the getter function for an attribute of an
            device object. May be omited if not of TYPE_SCALAR or TYPE_SPECTRUM.
        :type attr: Device.method
        :param data_type: How the data is updated. May be one of the following 
            - TYPE_STATIC no update,
            - TYPE_TIME append time stamp at trigger point,
            - TYPE_SCALAR append attribute value at trigger point,
            - or TYPE_SPECTRUM exchange data series by attribute values at
                trigger point.
        :type data_type: int|TYPE_STATIC|TYPE_TIME|TYPE_SCALAR|TYPE_SPECTRUM
        :param role: Should be ROLE_MASTER for data series which triggers the
            plot update.
        :type role: int|ROLE_SLAVE|ROLE_MASTER
        :param interval: Interval, to which the update_timer is set if of
            TYPE_TIME and ROLE_MASTER. May be omited otherwise.
        :type interval: float
        :param min_length: Data series will be extended to this length. May be
            omited.
        :type min_length: int
        :param length: Sets min_length and max_length to this value. -1 will
            will disable this feature. May be omited.
        :type length: int
        :param max_length: Data series will be shortened to this length. -1 will
            will disable this feature. May be omited.
        :type max_length: int
        :return: False on errors, True otherwise.
        :rtype: bool
        """
        if length > -1:
            min_length = length
            max_length = length
        if data is not None and type(data) != numpy.ndarray:
            data = numpy.array(data)
        if data is not None and data.shape[0] < min_length:
            data.resize(min_length)
        if data is not None and max_length > 0 and data.shape[0] > max_length:
            data.resize(max_length)
        datum = { \
                "data": data, \
                "data_type": data_type, \
                "min_length": min_length, \
                "length": length, \
                "max_length": max_length, \
                "items" : []}
        if data_type in [Plot.TYPE_SCALAR, Plot.TYPE_SPECTRUM]:
            try:
                if callable(attr):
                    device = attr.__self__
                    name = attr.__name__
                else:
                    return False
            except:
                return False
            datum["device"] = device  #device instance
            datum["name"] = name  #attribute name
            datum["getter"] = attr  #attribute getter method
            if data is None and data_type == Plot.TYPE_SCALAR:
                start_value = attr(refresh=True)
                datum["data"] = numpy.full(min_length, start_value)
            elif data is None:
                datum["data"] = numpy.array(attr(refresh=True))
                if datum["data"].shape[0] < min_length:
                    datum["data"].resize(min_length)
                if max_length > 0 and datum["data"].shape[0] > max_length:
                    datum["data"].resize(max_length)
        elif data_type == Plot.TYPE_TIME:
            datum["interval"] = interval
            if data is None:
                datum["data"] = numpy.linspace( \
                        -(min_length-1)*interval, 0, min_length)
        elif data_type != Plot.TYPE_STATIC:
            return False
        self.mutex.lock()
        self.data[i] = datum
        self.mutex.unlock()
        if role == Plot.ROLE_MASTER:
            self.set_master(i)
        return True

    def remove_plot_data(self, i):
        if i == self.master:
            self.unset_master()
        items = self.data[i]["items"]
        for item in items:
            self.remove_plot_item(item)
        del self.data[i]

    def add_plot_item(self, i, x, y, colour=Qt.red):
        """Add a plot item representing two already added data series.
        
        :param i: Id of the plot item. Should be ascending natural numbers 
            from 0 up.
        :type i: int
        :param x: Id of the data series holding the x values.
        :type x: int
        :param y: Id of the data series holding the y values.
        :type y: int
        :param colour: Colour of the plot item. The default is red.
        :type colour: str|QRgb|QColor|Qt.GlobalColor
        """
        self.items[i] = {"x": x, "y": y}
        self.data[x]["items"].append(i)
        self.data[y]["items"].append(i)
        self.items[i]["plot"] = PlotDataItem( \
                self.data[x]["data"], \
                self.data[y]["data"], \
                pen=QColor(colour))
        self.widget.addItem(self.items[i]["plot"])

    def remove_plot_item(self, i):
        self.mutex.lock()
        self.data[self.items[i]["x"]]["items"].remove(i)
        self.data[self.items[i]["y"]]["items"].remove(i)
        self.widget.removeItem(self.items[i]["plot"])
        del self.items[i]
        self.mutex.unlock()

    def add_line_item(self, i, **kwargs):
        self.mutex.lock()
        self.lines[i] = InfiniteLine(**kwargs)
        self.widget.addItem(self.lines[i])
        self.mutex.unlock()

    def remove_line_item(self, i):
        self.mutex.lock()
        self.widget.removeItem(self.lines[i])
        del self.lines[i]
        self.mutex.unlock()

    def set_master(self, i):
        """Set which data series will trigger a plot update.
        
        :param data: Id of the data series which triggers the update.
        :type data: int
        """
        self.mutex.lock()
        if self.master is not None and self.master != i:
            self.unset_master()
            self.data[i]["device"].value_changed.disconnect(self.update_values)
        if self.data[i]["data_type"] in [Plot.TYPE_SCALAR, Plot.TYPE_SPECTRUM]:
            self.data[i]["device"].value_changed.connect(self.update_values)
        elif self.data[i]["data_type"] == Plot.TYPE_TIME:
            self.update_timer.timeout.connect(self.update_values)
            self.update_timer_start = time.time()
            self.update_timer.start(self.data[i]["interval"] * 1000.)
        self.master = i
        self.mutex.unlock()

    def unset_master(self):
        self.mutex.lock()
        if self.data[self.master]["data_type"] in \
                [Plot.TYPE_SCALAR, Plot.TYPE_SPECTRUM]:
            self.data[self.master]["device"].value_changed.disconnect( \
                    self.update_values)
        elif self.data[self.master]["data_type"] == Plot.TYPE_TIME:
            self.update_timer.timeout.disconnect(self.update_values)
            self.update_timer.stop()
        self.mutex.unlock()

    def tie_x_range(self, data=-1):
        """Sets the plot x range to be the same as the given data series.
        
        :param data: Id of the data series holding the x values.
        :type data: int
        """
        self.x_range = data

    def clear(self):
        data = list(self.data.keys())
        for datum in data:
            self.remove_plot_data(datum)
        for line in list(self.lines.keys()):
            self.remove_line_item(line)
コード例 #28
0
class PyQtGraphDataPlot(QWidget):

    limits_changed = Signal()

    def __init__(self, parent=None):
        super(PyQtGraphDataPlot, self).__init__(parent)
        self._plot_widget = PlotWidget()
        self._plot_widget.getPlotItem().addLegend()
        self._plot_widget.setBackground((255, 255, 255))
        self._plot_widget.setXRange(0, 10, padding=0)
        vbox = QVBoxLayout()
        vbox.addWidget(self._plot_widget)
        self.setLayout(vbox)
        self._plot_widget.getPlotItem().sigRangeChanged.connect(self.limits_changed)

        self._curves = {}
        self._current_vline = None

    def add_curve(self, curve_id, curve_name, curve_color=QColor(Qt.blue), markers_on=False):
        pen = mkPen(curve_color, width=1)
        symbol = "o"
        symbolPen = mkPen(QColor(Qt.black))
        symbolBrush = mkBrush(curve_color)
        # this adds the item to the plot and legend
        if markers_on:
            plot = self._plot_widget.plot(name=curve_name, pen=pen, symbol=symbol, symbolPen=symbolPen, symbolBrush=symbolBrush, symbolSize=4)
        else:
            plot = self._plot_widget.plot(name=curve_name, pen=pen)
        self._curves[curve_id] = plot

    def remove_curve(self, curve_id):
        curve_id = str(curve_id)
        if curve_id in self._curves:
            self._plot_widget.removeItem(self._curves[curve_id])
            del self._curves[curve_id]
            self._update_legend()
           
    def _update_legend(self):
        # clear and rebuild legend (there is no remove item method for the legend...)
        self._plot_widget.clear()
        self._plot_widget.getPlotItem().legend.items = []
        for curve in self._curves.values():
            self._plot_widget.addItem(curve)
        if self._current_vline:
            self._plot_widget.addItem(self._current_vline)
 
    def redraw(self):
        pass

    def set_values(self, curve_id, data_x, data_y):
        curve = self._curves[curve_id]
        curve.setData(data_x, data_y)

    def vline(self, x, color):
        if self._current_vline:
            self._plot_widget.removeItem(self._current_vline)
        self._current_vline = self._plot_widget.addLine(x=x, pen=color)

    def set_xlim(self, limits):
        # TODO: this doesn't seem to handle fast updates well
        self._plot_widget.setXRange(limits[0], limits[1], padding=0)

    def set_ylim(self, limits):
        self._plot_widget.setYRange(limits[0], limits[1], padding=0)

    def get_xlim(self):
        x_range, _ = self._plot_widget.viewRange()
        return x_range

    def get_ylim(self):
        _, y_range = self._plot_widget.viewRange()
        return y_range
コード例 #29
0
class SpectrometerWidget(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.setLayout(QtGui.QHBoxLayout())
        self.resize(700, 500)
        self.wave = []
        self.spec = []
        self.time = None

        @inlineCallbacks
        def onInit():
            # connect to server
            ipAddress = TEST_SPECTROMETER_SERVER if DEBUG else SPECTROMETER_SERVER
            protocol = yield getProtocol(ipAddress)

            # create a client
            self.client = SpectrometerClient(protocol)
            self.wave = yield self.client.getWavelengths()
            self.numberToAverage = 1
            self.numberAcquired = 0
            self.darkSpectrum = np.zeros(NUM_PIXELS)
            self.specProcessed = np.zeros(NUM_PIXELS)
            self.gettingDark = False

            # set up overall layout: 1 large panel (plot) to left of 1 narrow /
            # panel (controls) all above 1 skinny panel (timestamp)
            fullLayout = QtGui.QVBoxLayout()
            self.layout().addLayout(fullLayout)

            topHalfLayout = QtGui.QHBoxLayout()
            fullLayout.addLayout(topHalfLayout)

            # define the plot
            self.plotWidget = PlotWidget()
            self.plot = self.plotWidget.plot()
            topHalfLayout.addWidget(self.plotWidget, 1)

            # define the controls panel
            cpLayout = QtGui.QVBoxLayout()
            topHalfLayout.addLayout(cpLayout)

            # define the capture controls (to go on controls panel)
            capLayout = QtGui.QVBoxLayout()

            def updatePlot(x, y):
                x = np.asarray(x)
                y = np.asarray(y)
                self.plotWidget.clear()
                self.plotWidget.plot(x, y, pen=mkPen("w", width=1))
                self.plotWidget.addItem(self.cursorVert)
                self.plotWidget.addItem(self.cursorHori)
                vertLabel.setText(str(round(self.cursorVert.pos()[0], 2)))
                horiLabel.setText(str(round(self.cursorHori.pos()[1], 2)))

            def avgSpec():
                oldAvgSpec = self.specProcessed
                addThis = self.spec - self.darkSpectrum
                self.numberAcquired += 1
                if self.numberAcquired < self.numberToAverage:
                    scale = self.numberAcquired
                else:
                    scale = self.numberToAverage
                newAvg = ((scale - 1) * oldAvgSpec + addThis) / scale
                self.specProcessed = newAvg

            @inlineCallbacks
            def capture():
                self.spec = yield self.client.getSpectrum()
                self.spec = np.asarray(self.spec)
                self.time = yield self.client.getLastTime()
                yield avgSpec()
                updatePlot(self.wave, self.specProcessed)
                self.timestamp.setText("last update: " + str(self.time))

            @inlineCallbacks
            def forcePress():
                self.numberAcquired = 0
                yield capture()

            forceButton = QtGui.QPushButton("force")
            forceButton.clicked.connect(forcePress)
            capLayout.addWidget(forceButton)

            autoRunLayout = QtGui.QHBoxLayout()

            self.freeRunCall = LoopingCall(capture)
            self.freeRunStatus = False

            def freeRun():
                if self.freeRunStatus:
                    freeButton.setText("start auto")
                    forceButton.setEnabled(True)
                    self.freeRunCall.stop()
                    self.freeRunStatus = False
                    self.numberAcquired = 0
                    return
                if not self.freeRunStatus:
                    freeButton.setText("stop auto")
                    forceButton.setEnabled(False)
                    self.freeRunCall.start(autoRateSpin.value(), now=True)
                    self.freeRunStatus = True

            freeButton = QtGui.QPushButton("start auto")
            freeButton.clicked.connect(freeRun)
            autoRunLayout.addWidget(freeButton)

            def updateAutoRate():
                if self.freeRunStatus:
                    self.freeRunCall.stop()
                    self.freeRunCall.start(autoRateSpin.value(), now=True)

            autoRateSpin = QtGui.QDoubleSpinBox()
            autoRateSpin.setRange(0.1, 10000.0)
            autoRateSpin.setValue(0.5)
            autoRateSpin.setSuffix("s")
            autoRateSpin.setSingleStep(0.1)
            autoRateSpin.valueChanged.connect(updateAutoRate)
            autoRunLayout.addWidget(autoRateSpin)

            capLayout.addLayout(autoRunLayout)

            cpLayout.addWidget(LabelWidget("capture", capLayout))

            # define the cursor/analysis controls
            curLayout = QtGui.QVBoxLayout()
            cpLayout.addWidget(LabelWidget("analysis", curLayout))

            self.cursorVert = InfiniteLine(
                pos=self.wave[NUM_PIXELS / 2], angle=90, pen=mkPen("g", width=0.5), movable=True
            )
            self.cursorHori = InfiniteLine(pos=0, angle=0, pen=mkPen("g", width=0.5), movable=True)
            self.plotWidget.addItem(self.cursorVert)
            self.plotWidget.addItem(self.cursorHori)

            vertLayout = QtGui.QHBoxLayout()
            vertName = QtGui.QLabel()
            vertName.setText("wavelength: ")
            vertLayout.addWidget(vertName)
            vertLabel = QtGui.QLabel()
            vertLabel.setText(str(round(self.cursorVert.pos()[0], 2)))
            vertLayout.addWidget(vertLabel)
            curLayout.addLayout(vertLayout)

            horiLayout = QtGui.QHBoxLayout()
            horiName = QtGui.QLabel()
            horiName.setText("intensity: ")
            horiLayout.addWidget(horiName)
            horiLabel = QtGui.QLabel()
            horiLabel.setText(str(round(self.cursorHori.pos()[0], 2)))
            horiLayout.addWidget(horiLabel)
            curLayout.addLayout(horiLayout)

            # define the acquisition controls
            acqLayout = QtGui.QVBoxLayout()
            cpLayout.addWidget(LabelWidget("acquisition", acqLayout))

            # integration
            integLayout = QtGui.QHBoxLayout()
            acqLayout.addLayout(integLayout)

            integTimeLabel = QtGui.QLabel()
            integTimeLabel.setText("integration: ")
            integLayout.addWidget(integTimeLabel)

            def integTimeUpdate():
                newTime = integTimeSpin.value()
                self.client.setIntegrationTime(newTime)

            integTimeSpin = QtGui.QDoubleSpinBox()
            integTimeSpin.setRange(0.001, 10)
            integTimeSpin.setDecimals(3)
            integTimeSpin.setValue(0.100)
            integTimeSpin.setSingleStep(0.05)
            integTimeSpin.setSuffix("s")
            integTimeSpin.editingFinished.connect(integTimeUpdate)
            integLayout.addWidget(integTimeSpin)

            # averaging
            avgLayout = QtGui.QHBoxLayout()
            acqLayout.addLayout(avgLayout)

            avgLabel = QtGui.QLabel()
            avgLabel.setText("averaging: ")
            avgLayout.addWidget(avgLabel)

            def avgUpdate():
                self.numberToAverage = avgSpin.value()

            avgSpin = QtGui.QSpinBox()
            avgSpin.setRange(1, 10000)
            avgSpin.setValue(1)
            avgSpin.valueChanged.connect(avgUpdate)
            avgLayout.addWidget(avgSpin)

            # dark spectrum
            darkLayout = QtGui.QHBoxLayout()
            acqLayout.addLayout(darkLayout)

            @inlineCallbacks
            def getDark():
                resetDark()
                self.gettingDark = True
                self.numberAcquired = 0
                wasInAuto = self.freeRunStatus
                if self.freeRunStatus:
                    freeRun()  # if in auto mode, stop it
                self.specProcessed = np.zeros(NUM_PIXELS)
                for specCount in range(self.numberToAverage):
                    yield capture()
                self.darkSpectrum = self.specProcessed
                self.specProcessed = np.zeros(NUM_PIXELS)
                if wasInAuto:
                    freeRun()
                self.numberAcquired = 0
                self.gettingDark = False

            darkSpecButton = QtGui.QPushButton("dark")
            darkSpecButton.clicked.connect(getDark)
            darkLayout.addWidget(darkSpecButton)

            def resetDark():
                self.darkSpectrum = np.zeros(NUM_PIXELS)
                self.specProcessed = np.zeros(NUM_PIXELS)

            resetDarkButton = QtGui.QPushButton("reset")
            resetDarkButton.clicked.connect(resetDark)
            darkLayout.addWidget(resetDarkButton)

            # define the timestamp panel
            self.timestamp = QtGui.QLabel()
            self.timestamp.setText("last update: never")
            self.timestamp.setAlignment(QtCore.Qt.AlignCenter)
            fullLayout.addWidget(self.timestamp)

        onInit()

    def refresh(self):
        time.sleep(0.5)
        self.update_plot()
        self.refresh()

    def closeEvent(self, event):
        reactor.stop()
        event.accept()
コード例 #30
0
class PyQtGraphDataPlot(QWidget):

    limits_changed = Signal()

    def __init__(self, parent=None):
        super(PyQtGraphDataPlot, self).__init__(parent)
        self._plot_widget = PlotWidget()
        self._plot_widget.getPlotItem().addLegend()
        self._plot_widget.setBackground((255, 255, 255))
        self._plot_widget.setXRange(0, 10, padding=0)
        vbox = QVBoxLayout()
        vbox.addWidget(self._plot_widget)
        self.setLayout(vbox)
        self._plot_widget.getPlotItem().sigRangeChanged.connect(
            self.limits_changed)

        self.bins = 10
        self.window = 100
        self._curves = {}
        self._current_vline = None

    def add_curve(self,
                  curve_id,
                  curve_name,
                  curve_color=QColor(Qt.blue),
                  markers_on=False):
        pen = mkPen(curve_color, width=1)
        # this adds the item to the plot and legend
        plot = self._plot_widget.plot(stepMode=True,
                                      fillLevel=0,
                                      brush=(0, 0, 255, 150))
        self._curves[curve_id] = plot

    def remove_curve(self, curve_id):
        curve_id = str(curve_id)
        if curve_id in self._curves:
            self._plot_widget.removeItem(self._curves[curve_id])
            del self._curves[curve_id]
            self._update_legend()

    def _update_legend(self):
        # clear and rebuild legend (there is no remove item method for the legend...)
        self._plot_widget.clear()
        self._plot_widget.getPlotItem().legend.items = []
        for curve in self._curves.values():
            self._plot_widget.addItem(curve)
        if self._current_vline:
            self._plot_widget.addItem(self._current_vline)

    def redraw(self):
        pass

    def set_values(self, curve_id, data_x, data_y):
        curve = self._curves[curve_id]
        if len(data_y) > 0:
            y, x = numpy.histogram(data_y[-self.window:], self.bins)
            curve.setData(x, y)
        else:
            curve.clear()
        self._plot_widget.autoRange()

    def vline(self, x, color):
        if self._current_vline:
            self._plot_widget.removeItem(self._current_vline)
        self._current_vline = self._plot_widget.addLine(x=x, pen=color)

    def set_xlim(self, limits):
        # TODO: this doesn't seem to handle fast updates well
        self._plot_widget.setXRange(limits[0], limits[1], padding=0)

    def set_ylim(self, limits):
        self._plot_widget.setYRange(limits[0], limits[1], padding=0)

    def get_xlim(self):
        x_range, _ = self._plot_widget.viewRange()
        return x_range

    def get_ylim(self):
        _, y_range = self._plot_widget.viewRange()
        return y_range
コード例 #31
0
ファイル: gui.py プロジェクト: a-fitzg/dionysus-gainsboro
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(799, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.graphicsView = PlotWidget(self.centralwidget)
        self.graphicsView.setGeometry(QtCore.QRect(10, 10, 551, 441))
        self.graphicsView.setObjectName("graphicsView")
        self.label1 = QtWidgets.QLabel(self.centralwidget)
        self.label1.setGeometry(QtCore.QRect(160, 460, 71, 16))
        self.label1.setObjectName("label1")
        self.label1.setStyleSheet("background-color:red")
        self.label2 = QtWidgets.QLabel(self.centralwidget)
        self.label2.setGeometry(QtCore.QRect(160, 480, 71, 13))
        self.label2.setObjectName("label2")
        self.label2.setStyleSheet("background-color:green")
        self.label3 = QtWidgets.QLabel(self.centralwidget)
        self.label3.setGeometry(QtCore.QRect(160, 500, 71, 13))
        self.label3.setObjectName("label3")
        self.label3.setStyleSheet("background-color:blue")
        self.listWidget = QtWidgets.QListWidget(self.centralwidget)
        self.listWidget.setGeometry(QtCore.QRect(620, 10, 141, 441))
        self.listWidget.setObjectName("listWidget")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 799, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

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

        loop = asyncio.get_event_loop()
        self.thread1 = RSSI(loop)
        self.thread = Worker()
        self.thread1.work()
        self.thread.start()
        self.thread.signal.connect(self.gui_update)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label1.setText(_translate("MainWindow", "TextLabel"))
        self.label2.setText(_translate("MainWindow", "TextLabel"))
        self.label3.setText(_translate("MainWindow", "TextLabel"))

    def gui_update(self, result):
        x_data = result[0]
        y_data = result[1]

        scatter = pg.ScatterPlotItem(x_data,
                                     y_data,
                                     size=10,
                                     brush=[pg.mkBrush(c) for c in "rgb"])
        self.graphicsView.clear()
        self.graphicsView.addItem(scatter)
        self.graphicsView.setXRange(0, 18, padding=0)
        self.graphicsView.setYRange(0, 12, padding=0)
        # coordinates = [x_data,y_data]
        coordinates = [[int(i[0])
                        for i in result], [int(i[1]) for i in result],
                       [int(i[2]) for i in result]]
        ## Room display
        count = 0
        while count < 3:
            if coordinates[count][0] > 3 and coordinates[count][
                    0] < 7 and coordinates[count][1] > 7 and coordinates[
                        count][1] < 11:
                if count == 0:
                    self.label1.setText('Room1')
                elif count == 1:
                    self.label2.setText('Room1')
                elif count == 2:
                    self.label3.setText('Room1')
            elif coordinates[count][0] > 12 and coordinates[count][
                    0] < 18.4 and coordinates[count][1] > 7 and coordinates[
                        count][1] < 11:
                if count == 0:
                    self.label1.setText('Room2')
                elif count == 1:
                    self.label2.setText('Room2')
                elif count == 2:
                    self.label3.setText('Room2')
            elif coordinates[count][1] > 11:
                if count == 0:
                    self.label1.setText('Corridor')
                elif count == 1:
                    self.label2.setText('Corridor')
                elif count == 2:
                    self.label3.setText('Corridor')
            else:
                if count == 0:
                    self.label1.setText('Open space')
                elif count == 1:
                    self.label2.setText('Open space')
                elif count == 2:
                    self.label3.setText('Open space')
            count += 1