Example #1
0
 def addGraphPlot(self):
     graph = GraphicsLayoutWidget(self.stockTab2)
     graph.setObjectName("stock UI")
     p1 = graph.addPlot(row=1, col=0)
     p2 = graph.addPlot(row=2, col=0)
     p1.showGrid(x=True, y=True, alpha=0.5)
     return graph
Example #2
0
 def populate_spectrogram_widget(self, widget: GraphicsLayoutWidget,
                                 game_name: str, player_name: PlayerName,
                                 electrode_name: str):
     # https://stackoverflow.com/questions/51312923/plotting-the-spectrum-of-a-wavfile-in-pyqtgraph-using-scipy-signal-spectrogram
     f, t, Sxx = self._acquire_spectrogram_signal(game_name, player_name,
                                                  electrode_name)
     plot = widget.addPlot()
     plot.setTitle('Frequency over time for electrode %s' %
                   ELECTRODES[electrode_name])
     img = ImageItem()
     plot.addItem(img)
     hist = HistogramLUTItem()
     hist.setImageItem(img)
     widget.addItem(hist)
     hist.setLevels(np.min(Sxx), np.max(Sxx))
     hist.gradient.restoreState({
         'mode':
         'rgb',
         'ticks': [(0.5, (0, 182, 188, 255)), (1.0, (246, 111, 0, 255)),
                   (0.0, (75, 0, 113, 255))]
     })
     img.setImage(Sxx)
     img.scale(t[-1] / np.size(Sxx, axis=1), f[-1] / np.size(Sxx, axis=0))
     plot.setLimits(xMin=0, xMax=t[-1], yMin=0, yMax=f[-1])
     plot.setLabel('bottom', "Time", units='s')
     plot.setLabel('left', "Frequency", units='Hz')
Example #3
0
 def populate_eeg_graph_widget(self, widget: GraphicsLayoutWidget,
                               game_name: str, player_name: PlayerName,
                               electrode_name: str):
     data = self._acquire_eeg_signal(game_name, player_name, electrode_name)
     time = self._acquire_eeg_signal(game_name, player_name, 'time')
     plot = widget.addPlot()
     plot.plot(time, data, pen=mkPen({'color': "37AAD2"}))
     plot.setTitle('Amplitude of the EEG signal for electrode %s' %
                   ELECTRODES[electrode_name])
     plot.setLabel('bottom', "Time", units='s')
     plot.setLabel('left', "Amplitude", units='uV')
Example #4
0
def get_spectrogram(wav: WavFile, graphics_layout: pyqtgraph.GraphicsLayoutWidget):
    f, t, Sxx = signal.spectrogram(wav.data, wav.rate)

    # Interpret image data as row-major instead of col-major
    pyqtgraph.setConfigOptions(imageAxisOrder='row-major')
    pyqtgraph.mkQApp()
    graphics_layout.clear()
    plot_widget = graphics_layout.addPlot()
    # A plot area (ViewBox + axes) for displaying the image

    # Item for displaying image data
    img = pyqtgraph.ImageItem()
    plot_widget.addItem(img)
    # Add a histogram with which to control the gradient of the image
    hist = pyqtgraph.HistogramLUTItem()
    # Link the histogram to the image
    hist.setImageItem(img)
    # If you don't add the histogram to the window, it stays invisible, but I find it useful.
    graphics_layout.addItem(hist)
    # Show the window
    graphics_layout.show()
    # Fit the min and max levels of the histogram to the data available
    #print("min: "+ str(np.min(Sxx)) + "max:" + str(np.max(Sxx)))
    hist.setLevels(0, 40000)
    # This gradient is roughly comparable to the gradient used by Matplotlib
    # You can adjust it and then save it using hist.gradient.saveState()
    hist.gradient.restoreState(
        {'mode': 'rgb',
         'ticks': [(0.5, (0, 182, 188, 255)),
                   (1.0, (246, 111, 0, 255)),
                   (0.0, (75, 0, 113, 255))]})
    # Sxx contains the amplitude for each pixel
    img.setImage(Sxx)
    # Scale the X and Y Axis to time and frequency (standard is pixels)
    img.scale(t[-1] / np.size(Sxx, axis=1),
              f[-1] / np.size(Sxx, axis=0))
    # Limit panning/zooming to the spectrogram
    plot_widget.setLimits(xMin=0, xMax=t[-1], yMin=0, yMax=f[-1])
    # Add labels to the axis
    plot_widget.setLabel('bottom', "Time", units='s')
    # If you include the units, Pyqtgraph automatically scales the axis and adjusts the SI prefix (in this case kHz)
    plot_widget.setLabel('left', "Frequency", units='Hz')
Example #5
0
class Ui_MainWindow(QMainWindow):


    def __init__(self):
        super(Ui_MainWindow, self).__init__()
        self.traindata = []
        self.numberofclasses = 0
        self.trueTestDataLabels= []
        self.labeltestdata= []
        self.testData = []

    def setupUi(self):
        self.centralwidget = QtWidgets.QWidget()
        self.setMinimumSize(QtCore.QSize(766, 430))
        self.setMaximumSize(QtCore.QSize(766, 430))
        self.centralwidget.setObjectName("centralwidget")
        self.graphicsView = GraphicsLayoutWidget(self.centralwidget)
        self.graphicsView.setGeometry(QtCore.QRect(10, 80, 751, 321))
        self.graphicsView.setObjectName("graphicsView")
        self.pushButtonExplore = QtWidgets.QPushButton(self.centralwidget)
        self.pushButtonExplore.setGeometry(QtCore.QRect(12, 402, 337, 27))
        self.pushButtonExplore.setObjectName("pushButtonExplore")
        self.graphicsView_2 = GraphicsLayoutWidget(self.centralwidget)
        self.graphicsView_2.setGeometry(QtCore.QRect(10, 440, 751, 221))
        self.graphicsView_2.setObjectName("graphicsView_2")
        self.widget = QtWidgets.QWidget(self.centralwidget)
        self.widget.setGeometry(QtCore.QRect(11, 11, 750, 62))
        self.widget.setObjectName("widget")
        self.gridLayout = QtWidgets.QGridLayout(self.widget)
        self.gridLayout.setContentsMargins(0, 0, 0, 0)
        self.gridLayout.setObjectName("gridLayout")
        self.pushButtotLoadIris = QtWidgets.QPushButton(self.widget)
        self.pushButtotLoadIris.setObjectName("pushButtotLoadIris")
        self.gridLayout.addWidget(self.pushButtotLoadIris, 0, 0, 1, 2)
        self.checkBoxSuspended = QtWidgets.QCheckBox(self.widget)
        self.checkBoxSuspended.setObjectName("checkBoxSuspended")
        self.gridLayout.addWidget(self.checkBoxSuspended, 0, 2, 1, 3)
        self.pushButtonCheckTest = QtWidgets.QPushButton(self.widget)
        self.pushButtonCheckTest.setObjectName("pushButtonCheckTest")
        self.gridLayout.addWidget(self.pushButtonCheckTest, 0, 5, 1, 3)
        self.pushButtonGenerate = QtWidgets.QPushButton(self.widget)
        self.pushButtonGenerate.setObjectName("pushButtonGenerate")
        self.gridLayout.addWidget(self.pushButtonGenerate, 1, 0, 1, 1)
        self.label_3 = QtWidgets.QLabel(self.widget)
        self.label_3.setObjectName("label_3")
        self.gridLayout.addWidget(self.label_3, 1, 1, 1, 2)
        self.spinBoxClasses = QtWidgets.QSpinBox(self.widget)
        self.spinBoxClasses.setMinimum(1)
        self.spinBoxClasses.setMaximum(8)
        self.spinBoxClasses.setObjectName("spinBoxClasses")
        self.gridLayout.addWidget(self.spinBoxClasses, 1, 3, 1, 1)
        self.label_2 = QtWidgets.QLabel(self.widget)
        self.label_2.setObjectName("label_2")
        self.gridLayout.addWidget(self.label_2, 1, 4, 1, 1)
        self.spinBoxElements = QtWidgets.QSpinBox(self.widget)
        self.spinBoxElements.setMinimum(1)
        self.spinBoxElements.setProperty("value", 20)
        self.spinBoxElements.setObjectName("spinBoxElements")
        self.gridLayout.addWidget(self.spinBoxElements, 1, 5, 1, 1)
        self.label = QtWidgets.QLabel(self.widget)
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 1, 6, 1, 1)
        self.spinBoxK = QtWidgets.QSpinBox(self.widget)
        self.spinBoxK.setMinimum(3)
        self.spinBoxK.setSingleStep(2)
        self.spinBoxK.setObjectName("spinBoxK")
        self.gridLayout.addWidget(self.spinBoxK, 1, 7, 1, 1)
        self.retranslateUi()
        QtCore.QMetaObject.connectSlotsByName(self)
        self.w1 = self.graphicsView.addPlot()
        self.w2 = self.graphicsView_2.addPlot()
        self.legend= self.w2.addLegend()
        self.w1.scene().sigMouseClicked.connect(self.onClick)
        self.pushButtonGenerate.clicked.connect(self.generateDate)
        self.pushButtotLoadIris.clicked.connect(self.loadIris)
        self.pushButtonCheckTest.clicked.connect(self.checkTest)
        self.pushButtonExplore.clicked.connect(self.explore)
        self.setCentralWidget(self.centralwidget)
    def retranslateUi(self):
        _translate = QtCore.QCoreApplication.translate
        self.pushButtonExplore.setText(_translate("MainWindow", "Исследование влияния k для разных метрик"))
        self.pushButtotLoadIris.setText(_translate("MainWindow", "Загрузить данные с рисом"))
        self.checkBoxSuspended.setText(_translate("MainWindow", "Использовать взвешенный kNN"))
        self.pushButtonCheckTest.setText(_translate("MainWindow", "Проверить тестовую выборку"))
        self.pushButtonGenerate.setText(_translate("MainWindow", "Сгенерировать выборку"))
        self.label_3.setText(_translate("MainWindow", "Кол-во классов"))
        self.label_2.setText(_translate("MainWindow", "Кол-во элементов"))
        self.label.setText(_translate("MainWindow", "Кол-во соседей(K)"))

    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Escape:
            self.close()
        if e.key() == Qt.Key_Delete:
            self.w1.clear()
            classes = []
            i = 0
            while i < 20:
                classes.append([])
                i += 1

            for i in self.traindata:
                classes[i[1]].append(np.asarray(i[0]))
            i = 0
            for j in classes:
                myS = pg.ScatterPlotItem(size=10, pen=pg.mkPen(colors[i]), brush=pg.mkBrush(255, 255, 255, 120))
                myspots = []
                if (len(j)):
                    for k in j:
                        myspots.append({'pos': k, 'data': i})
                    i += 1
                    myS.addPoints(myspots)
                    self.w1.addItem(myS)

    def onClick(self, event):
        if len(self.traindata) == 0:
            return 1
        vb = self.w1.vb
        mousePoint = vb.mapSceneToView(event.scenePos())
        testdata = [[mousePoint.x(), mousePoint.y()]]
        testDataLabels = classifyKNN(self.traindata, testdata, self.spinBoxK.value(), self.numberofclasses,self.checkBoxSuspended.isChecked(),0)
        myS = pg.ScatterPlotItem(size=10, pen=pg.mkPen(colors[testDataLabels[0]]), brush=pg.mkBrush(255, 255, 255, 120))
        myspots = []
        myspots.append({'pos': np.asarray([mousePoint.x(), mousePoint.y()]), 'data': testDataLabels[0]})
        myS.addPoints(myspots)
        self.w1.addItem(myS)
        self.traindata.append([[mousePoint.x(), mousePoint.y()], testDataLabels[0]])
        print(self.traindata)


    def loadIris(self):

        with open('train', 'rb') as fp:
            train = pickle.load(fp)
        with open('labels', 'rb') as fp:
            labels = pickle.load(fp)
        self.w1.clear()

        self.numberofclasses = 3
        self.traindata = []
        n = 0
        for i in train:
             self.traindata.append([])
             self.traindata[n].append(i.tolist())
             self.traindata[n].append(labels[n])
             n += 1

        # testDataLabels = classifyKNN(trainData, testData, 5, 2)

        trainData, self.trueTestDataLabels = splitTrainTest(self.traindata, 0.33)

        self.traindata = trainData
        self.testData = [self.trueTestDataLabels[i][0] for i in range(len(self.trueTestDataLabels))]
      #  self.labeltestdata = classifyKNN(trainData, self.testData, self.spinBoxK.value(), self.numberofclasses,self.checkBoxSuspended.isChecked())

        classes = []
        i = 0
        while i < 20:
            classes.append([])
            i += 1

        for i in self.traindata:
            classes[i[1]].append(np.asarray(i[0]))
        i = 0
        for j in classes:
            myS = pg.ScatterPlotItem(size=10, pen=pg.mkPen(colors[i]), brush=pg.mkBrush(255, 255, 255, 120))
            myspots = []
            if (len(j)):
                for k in j:
                    myspots.append({'pos': k, 'data': i})
                i += 1
                myS.addPoints(myspots)
                self.w1.addItem(myS)
        self.spinBoxClasses.setValue(3)
        self.spinBoxK.setValue(4)
        self.spinBoxK.setSingleStep(3)
        self.spinBoxElements.setValue(75)

    def checkTest(self):
        if len(self.traindata) == 0:
            return 1
        print(self.testData)
        self.labeltestdata = classifyKNN(self.traindata, self.testData, self.spinBoxK.value(), self.numberofclasses,self.checkBoxSuspended.isChecked(),0)
        x = sum([int(self.labeltestdata[i] == self.trueTestDataLabels[i][1]) for i in
                 range(len(self.trueTestDataLabels))]) / float(
            len(self.trueTestDataLabels))

        classes = []
        i = 0
        while i < 20:
            classes.append([])
            i += 1

        for i in self.trueTestDataLabels:
            classes[i[1]].append(np.asarray(i[0]))
        i = 0
        for j in classes:
            myS = pg.ScatterPlotItem(size=10, pen=pg.mkPen(colors[i]), brush=pg.mkBrush(255, 255, 255, 120))
            myspots = []
            if (len(j)):
                for k in j:
                    myspots.append({'pos': k, 'data': i})
                i += 1
                myS.addPoints(myspots)
                self.w1.addItem(myS)

        dialog = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Information,
                                       "Точность классификации ", str(x),
                                       buttons=QtWidgets.QMessageBox.Ok
                                       ,
                                       parent=None)
        result = dialog.exec_()

    def changeK(self, i):

        self.spinBoxK.setSingleStep(i)
        self.spinBoxK.setMinimum(i + 1)
        self.spinBoxK.setProperty("value", i + 1)

    def generateDate(self):
        self.w1.clear()
        data = generateData(self.spinBoxElements.value(), self.spinBoxClasses.value())
        self.numberofclasses = self.spinBoxClasses.value()
        trainData, self.trueTestDataLabels = splitTrainTest(data, 0.33)

        self.traindata = trainData
        self.testData = [self.trueTestDataLabels[i][0] for i in range(len(self.trueTestDataLabels))]
       # self.labeltestdata = classifyKNN(trainData, self.testData, self.spinBoxK.value(), self.numberofclasses,self.checkBoxSuspended.isChecked())

        classes = []
        i = 0
        while i < 20:
            classes.append([])
            i += 1

        for i in trainData:
            classes[i[1]].append(np.asarray(i[0]))
        i = 0
        for j in classes:
            myS = pg.ScatterPlotItem(size=10, pen=pg.mkPen(colors[i]), brush=pg.mkBrush(255, 255, 255, 120))
            myspots = []
            if (len(j)):
                for k in j:
                    myspots.append({'pos': k, 'data': i})
                i += 1
                myS.addPoints(myspots)
                self.w1.addItem(myS)

    def explore(self):
        if not(self.traindata):
            return
        self.w2.clear()
        self.legend.scene().removeItem(self.legend)
        self.legend = self.w2.addLegend()
        myspots = []
        i = self.spinBoxK.value()
        while i < self.spinBoxElements.value():
            self.labeltestdata = classifyKNN(self.traindata,
                                             self.testData,
                                             i,
                                             self.numberofclasses,
                                             self.checkBoxSuspended.isChecked(),
                                             0)
            myspots.append([i, sum([int(self.labeltestdata[i] == self.trueTestDataLabels[i][1]) for i in
                                    range(len(self.trueTestDataLabels))]) / float(
                len(self.trueTestDataLabels))])
            i += self.spinBoxK.singleStep()
        self.w2.plot(x=[x[0] for x in myspots],
                     y=[y[1] for y in myspots],
                     symbol='o',
                     name = "Евклидово расстояние",
                     pen = (0, 0, 255),

                     )


        myspots = []
        i = self.spinBoxK.value()
        while i < self.spinBoxElements.value():
            self.labeltestdata = classifyKNN(self.traindata,
                                             self.testData,
                                             i,
                                             self.numberofclasses,
                                             self.checkBoxSuspended.isChecked(),
                                             1)
            myspots.append([i, sum([int(self.labeltestdata[i] == self.trueTestDataLabels[i][1]) for i in
                                    range(len(self.trueTestDataLabels))]) / float(
                len(self.trueTestDataLabels))])
            i += self.spinBoxK.singleStep()
        self.w2.plot(x=[x[0] for x in myspots],
                     y=[y[1] for y in myspots],
                     pen=(255, 0, 0),
                     symbolBrush=(255, 0, 0),
                     symbolPen='w',
                     name="Манхэттенское расстояние")
        myspots = []
        i = self.spinBoxK.value()
        while i < self.spinBoxElements.value():
            self.labeltestdata = classifyKNN(self.traindata,
                                             self.testData,
                                             i,
                                             self.numberofclasses,
                                             self.checkBoxSuspended.isChecked(),
                                             2)
            myspots.append([i, sum([int(self.labeltestdata[i] == self.trueTestDataLabels[i][1]) for i in
                                    range(len(self.trueTestDataLabels))]) / float(
                len(self.trueTestDataLabels))])
            i += self.spinBoxK.singleStep()
        self.w2.plot(x=[x[0] for x in myspots], y=[y[1] for y in myspots],
                     pen=(0, 255, 0),
                     symbolBrush=(0, 255, 0),
                     symbolPen='g',
                     name="Расстояние Чебышева")
        self.w2.setLabels(title='Сравнение метрик', left="Точность", bottom="K")

        self.setMinimumSize(QtCore.QSize(766, 717))
        self.setMaximumSize(QtCore.QSize(766, 717))
Example #6
0
class EEGViewer(QThread):
    """docstring for EEGViewer"""

    StoppedState = 0
    PausedState = 1
    RunningState = 2

    def __init__(self, mode='single', rows=4):
        super(EEGViewer, self).__init__()
        self.mode = mode
        self.rows = rows
        self.view = GraphicsLayoutWidget()
        self.view.setAntialiasing(True)
        self.view.setWindowTitle('EEG Viewer')
        self.state = self.StoppedState
        self.position = 0
        self.maxPosition = 0
        self.plotItem = list()
        self.plotTrace = dict()
        # Holders
        self.wait = 0
        self.wsize = 0
        self.hsize = 0
        self.color = dict()
        self.window = list([0, 0])
        self.channel = list()

    def widget(self):
        return self.view

    def show(self):
        self.view.show()

    def hide(self):
        self.view.hide()

    def getState(self):
        return self.state

    def isVisible(self):
        return self.view.isVisible()

    def setSize(self, width, height):
        self.view.resize(width, height)

    def configure(self, channel, color, wsize, fs=0):
        # Link params
        nCh = len(channel)
        self.wait = 1 / (fs * nCh) if fs > 0 else 0
        self.wsize = wsize
        self.hsize = wsize / 2
        self.color = color
        self.channel = channel
        self.window = np.array([0, wsize])
        # Remove previous items and traces
        self.view.clear()
        self.plotItem.clear()
        self.plotTrace.clear()
        # Create new canvas
        if self.mode == 'single':
            self.singleLayout()
        else:
            self.multipleLayout()

    def singleLayout(self):
        canvas = self.view.addPlot(0, 0)
        canvas.disableAutoRange()
        canvas.setClipToView(True)
        canvas.setLimits(yMin=0, yMax=1)
        canvas.setDownsampling(mode='subsample')
        canvas.showGrid(x=True, y=True, alpha=0.25)
        for ch in self.channel:
            pen = mkPen(color=self.color[ch], width=2)
            self.plotTrace[ch] = canvas.plot(pen=pen)
        self.plotItem.append(canvas)

    def multipleLayout(self):
        col = 0
        rowLimit = self.rows
        for i, ch in enumerate(self.channel):
            pen = mkPen(color=self.color[ch], width=2)
            canvas = self.view.addPlot(i % rowLimit, col)
            canvas.disableAutoRange()
            canvas.setClipToView(True)
            canvas.setLimits(yMin=0, yMax=1)
            canvas.setDownsampling(mode='subsample')
            canvas.showGrid(x=True, y=True, alpha=0.25)
            self.plotItem.append(canvas)
            self.plotTrace[ch] = canvas.plot(pen=pen)
            if (i + 1) % rowLimit == 0:
                col += 1

    def plotData(self, D):
        for ch in self.channel:
            self.plotTrace[ch].setData(D[ch].values)
        self.position = 0
        self.maxPosition = D.index.size

    def addMark(self, position, label=None):
        for canvas in self.plotItem:
            pen = mkPen(color='g', width=2.5, style=Qt.DashLine)
            hpen = mkPen(color='r', width=2.5, style=Qt.DashLine)
            mark = canvas.addLine(x=position,
                                  pen=pen,
                                  label=label,
                                  labelOpts={'position': 0.9},
                                  movable=True,
                                  hoverPen=hpen)
            return mark

    def setPosition(self, position):
        self.window[0] = position - self.hsize
        self.window[1] = position + self.hsize
        self.position = position
        self.update()

    def update(self):
        for plot in self.plotItem:
            plot.setRange(xRange=self.window)
        self.position += 1 if self.position < self.maxPosition else 0

    def play(self):
        self.state = self.RunningState
        self.start()

    def pause(self):
        self.state = self.PausedState

    def toggle(self):
        self.state = self.PausedState if self.state == self.RunningState else self.RunningState

    def stop(self):
        self.state = self.StoppedState
        self.quit()
        self.setPosition(0)

    def run(self):
        while True:
            if self.state == self.RunningState:
                self.setPosition(self.position)
            elif self.state == self.PausedState:
                pass
            else:
                break
            sleep(self.wait)
class Ui_MainWindow(object):

    def variables(self):
        self.D1_='D1'
        self.D2_='D2'
        self.D3_='D3'
        self.AVF_='AVF'
        self.AVR_='AVR'
        self.AVL_='AVL'
        self.GENRAL_='GENRAL'

    

    def setupUi(self, MainWindow):

        try:
            base_path= sys._MEIPASS
        except Exception:
            base_path=os.path.abspath(".")
        


        path1 = os.path.join(base_path, "imagen1.jpeg")
        path2 = os.path.join(base_path, "imagen2.jpeg")


        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1350, 747)
        #MainWindow.setStyleSheet("background-color: blue;")
        
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButtonAbrir = QtWidgets.QPushButton(self.centralwidget)
        self.pushButtonAbrir.setGeometry(QtCore.QRect(280, 10, 300, 32))
        self.pushButtonAbrir.setObjectName("pushButtonAbrir")
        #self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        #self.pushButton_2.setGeometry(QtCore.QRect(510, 90, 151, 41))
        #self.pushButton_2.setObjectName("pushButton_2")

        self.graphicsView = GraphicsLayoutWidget(self.centralwidget)
        self.graphicsView.setGeometry(QtCore.QRect(750, 230, 585, 370))
        self.graphicsView.setObjectName("graphicsView")
        
        #self.graphicsView.setBackground(background=None)

        self.label_7 = QtWidgets.QLabel(self.centralwidget)
        self.label_7.setGeometry(QtCore.QRect(1050, 1, 300, 100))
        self.label_7.setObjectName("label_7")
        pixmap = QPixmap(path1)
        self.label_7.setPixmap(pixmap)


        self.label_8 = QtWidgets.QLabel(self.centralwidget)
        self.label_8.setGeometry(QtCore.QRect(800, 1, 300, 100))
        self.label_8.setObjectName("label_8")
        pixmap = QPixmap(path2)
        self.label_8.setPixmap(pixmap)

        #Persona que creo el programa
        self.label_9 = QtWidgets.QLabel(self.centralwidget)
        self.label_9.setGeometry(QtCore.QRect(1000, 630, 2000, 70))
        self.label_9.setObjectName("label_9")

        #Nombre del proyecto
        self.label_10 = QtWidgets.QLabel(self.centralwidget)
        self.label_10.setGeometry(QtCore.QRect(1000, 595, 2000, 70))
        self.label_10.setObjectName("label_10")

        #Parametros de la persona
        self.label_nom = QtWidgets.QLabel(self.centralwidget)
        self.label_nom.setGeometry(QtCore.QRect(800, 20, 800, 200))
        self.label_nom.setObjectName("label_nom")

        self.label_edad = QtWidgets.QLabel(self.centralwidget)
        self.label_edad.setGeometry(QtCore.QRect(800, 60, 800, 200))
        self.label_edad.setObjectName("label_edad")

        self.label_sexo = QtWidgets.QLabel(self.centralwidget)
        self.label_sexo.setGeometry(QtCore.QRect(800, 100, 800, 200))
        self.label_sexo.setObjectName("label_sexo")

        self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox.setGeometry(QtCore.QRect(20, 40, 675, 841))
        self.groupBox.setObjectName("groupBox")
        
        self.graphicD1 = GraphicsLayoutWidget(self.groupBox)
        self.graphicD1.setObjectName("graphicD1")
        self.graphicD1.setGeometry(QtCore.QRect(65, 30, 1000, 110))
        self.graphicD1.setBackground(background=None)

        self.graphicD2 = GraphicsLayoutWidget(self.groupBox)
        self.graphicD2.setObjectName("graphicD2")
        self.graphicD2.setGeometry(QtCore.QRect(65, 130, 1000, 110))
        self.graphicD2.setBackground(background=None)

        self.graphicD3 = GraphicsLayoutWidget(self.groupBox)
        self.graphicD3.setObjectName("graphicD3")
        self.graphicD3.setGeometry(QtCore.QRect(65, 230, 1000, 110))
        self.graphicD3.setBackground(background=None)

        self.graphicD3_2 = GraphicsLayoutWidget(self.groupBox)
        self.graphicD3_2.setObjectName("graphicD3_2")
        self.graphicD3_2.setGeometry(QtCore.QRect(65, 330, 1000, 110))
        self.graphicD3_2.setBackground(background=None)

        self.graphicD3_3 = GraphicsLayoutWidget(self.groupBox)
        self.graphicD3_3.setGeometry(QtCore.QRect(65, 430, 1000, 110))
        self.graphicD3_3.setObjectName("graphicD3_3")
        self.graphicD3_3.setBackground(background=None)

        self.graphicD3_4 = GraphicsLayoutWidget(self.groupBox)
        self.graphicD3_4.setObjectName("graphicD3_4")
        self.graphicD3_4.setGeometry(QtCore.QRect(65, 530, 1000, 110))
        self.graphicD3_4.setBackground(background=None)
       

        self.label = QtWidgets.QLabel(self.groupBox)
        self.label.setGeometry(QtCore.QRect(10, 65, 50, 24))
        self.label.setObjectName("label")
        self.label_2 = QtWidgets.QLabel(self.groupBox)
        self.label_2.setGeometry(QtCore.QRect(10, 165, 50, 24))
        self.label_2.setObjectName("label_2")
        self.label_3 = QtWidgets.QLabel(self.groupBox)
        self.label_3.setGeometry(QtCore.QRect(10, 265, 50, 24))
        self.label_3.setObjectName("label_3")

        self.label_4 = QtWidgets.QLabel(self.groupBox)
        self.label_4.setGeometry(QtCore.QRect(10, 365, 60, 24))
        self.label_4.setObjectName("label_4")
        self.label_5 = QtWidgets.QLabel(self.groupBox)
        self.label_5.setGeometry(QtCore.QRect(10, 465, 60, 24))
        self.label_5.setObjectName("label_5")
        self.label_6 = QtWidgets.QLabel(self.groupBox)
        self.label_6.setGeometry(QtCore.QRect(10, 565, 60, 24))
        self.label_6.setObjectName("label_6")
        
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 863, 22))
        self.menubar.setObjectName("menubar")
    
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        
        self.retranslateUi(MainWindow)
        self.pushButtonAbrir.clicked.connect(self.mybutton_clicked)
        #self.pushButton_2.clicked.connect(self.generatedReport)

        #Cajas de texto

        self.line_nom = QtWidgets.QLineEdit(self.centralwidget)
        self.line_nom.resize(200, 32)
        self.line_nom.move(875, 100)

        self.line_edad = QtWidgets.QLineEdit(self.centralwidget)
        self.line_edad.resize(200, 32)
        self.line_edad.move(875, 140)

        #self.line_sexo = QtWidgets.QLineEdit(self.centralwidget)
        #self.line_sexo.resize(200, 32)
        #self.line_sexo.move(875, 180)

        self.combo_sexo = QtWidgets.QComboBox(self.centralwidget)
        self.combo_sexo.resize(200, 32)
        self.combo_sexo.move(875, 180)
        self.combo_sexo.addItems(["None","Male","Female" ])
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        



    def mybutton_clicked(self):
        try:
            self.variables()
            #Nombre de encabezados del archivo CSV
            

            persona = {"Nombre":self.line_nom.text(),"Edad":self.line_edad.text(),"Genero":self.combo_sexo.currentText()}
            combo_textt =self.combo_sexo.currentText()
            #print(combo_textt)

            filename= QtWidgets.QFileDialog.getOpenFileName()
            df = pandas.read_csv(filename[0])

            x_max=df['x'].max()

            a=(df["x"])/4
            b= (df["x"]+x_max)/4
            c= (df["x"]+(2*x_max))/4
            d= (df["x"]+(3*x_max))/4
            r = pandas.concat([a,b,c,d])
            s= pandas.concat([df[self.D1_],df[self.D1_],df[self.D1_],df[self.D1_]])
            t= pandas.concat([df[self.D2_],df[self.D2_],df[self.D2_],df[self.D2_]])
            u= pandas.concat([df[self.D3_],df[self.D3_],df[self.D3_],df[self.D3_]])
            v= pandas.concat([df[self.AVF_],df[self.AVF_],df[self.AVF_],df[self.AVF_]])
            w= pandas.concat([df[self.AVR_],df[self.AVR_],df[self.AVR_],df[self.AVR_]])
            x= pandas.concat([df[self.AVL_],df[self.AVL_],df[self.AVL_],df[self.AVL_]])
            y= pandas.concat([df[self.GENRAL_],df[self.GENRAL_],df[self.GENRAL_],df[self.GENRAL_]])
            df = pandas.DataFrame({"x":r, "D1":s,"D2":t,"D3":u,"AVF":v,"AVR":w,"AVL":x,"GENRAL":y})




            self.d1_INTERVAL_1=df.query('x >= 3.03 & x <= 3.08')#st
            self.d1_INTERVAL_2=df.query('x >= 1.7 & x <= 1.9')#t
            self.d1_INTERVAL_3=df.query('x >= 4.2 & x <= 4.3')#p
            self.d1_INTERVAL_1_MAX= self.d1_INTERVAL_1[self.D1_].max()
            self.d1_INTERVAL_2_MAX= self.d1_INTERVAL_2[self.D1_].max()
            self.d1_INTERVAL_3_MAX= self.d1_INTERVAL_3[self.D1_].max()

            self.d2_INTERVAL_1=df.query('x >= 15.4 & x <= 15.44')#ST
            self.d2_INTERVAL_2=df.query('x >= 16.2 & x <= 16.4')#T
            self.d2_INTERVAL_3=df.query('x >= 16.6 & x <= 16.7')#P
            self.d2_INTERVAL_1_MAX= self.d2_INTERVAL_1[self.D2_].max()
            self.d2_INTERVAL_2_MAX= self.d2_INTERVAL_2[self.D2_].max()
            self.d2_INTERVAL_3_MAX= self.d2_INTERVAL_3[self.D2_].max()

            self.d3_INTERVAL_1=df.query('x >= 67.01 & x <= 67.05')#st
            self.d3_INTERVAL_2=df.query('x >= 49.85 & x <= 50')#t
            self.d3_INTERVAL_3=df.query('x >= 50.35 & x <= 50.45')#p
            self.d3_INTERVAL_1_MAX= self.d3_INTERVAL_1[self.D3_].max()
            self.d3_INTERVAL_2_MAX= self.d3_INTERVAL_2[self.D3_].max()
            self.d3_INTERVAL_3_MAX= self.d3_INTERVAL_3[self.D3_].max()

            self.avf_INTERVAL_1=df.query('x >= 111.635    & x <= 111.7')#st
            self.avf_INTERVAL_2=df.query('x >= 113.82 & x <= 114')#t
            self.avf_INTERVAL_3=df.query('x >= 153.4 & x <= 153.545')#p
            self.avf_INTERVAL_1_MAX= self.avf_INTERVAL_1[self.AVF_].max()
            self.avf_INTERVAL_2_MAX= self.avf_INTERVAL_2[self.AVF_].max()
            self.avf_INTERVAL_3_MAX= self.avf_INTERVAL_3[self.AVF_].max()

            self.avr_INTERVAL_1=df.query('x >= 99.27 & x <= 99.29')#st
            self.avr_INTERVAL_2=df.query('x >= 102.06& x <= 102.26')#t
            self.avr_INTERVAL_3=df.query('x >= 105.95 & x <= 106.09')#p
            self.avr_INTERVAL_1_MAX= self.avr_INTERVAL_1[self.AVR_].min()
            self.avr_INTERVAL_2_MAX= self.avr_INTERVAL_2[self.AVR_].min()
            self.avr_INTERVAL_3_MAX= self.avr_INTERVAL_3[self.AVR_].min()

            self.avl_INTERVAL_1=df.query('x >= 95.93 & x <= 96.12')#st
            self.avl_INTERVAL_2=df.query('x >= 104.75 & x <= 104.8')#t
            self.avl_INTERVAL_3=df.query('x >= 130.67 & x <= 130.81')#p
            self.avl_INTERVAL_1_MAX= self.avl_INTERVAL_1[self.AVL_].max()
            self.avl_INTERVAL_2_MAX= self.avl_INTERVAL_2[self.AVL_].max()
            self.avl_INTERVAL_3_MAX= self.avl_INTERVAL_3[self.AVL_].max()


            #VALORES ST Y T

            values_ST_T ={  self.D1_:
                                {
                                    "d1_INTERVAL_1_MAX":self.d1_INTERVAL_1_MAX,
                                    "d1_INTERVAL_2_MAX":self.d1_INTERVAL_2_MAX,
                                    "d1_INTERVAL_3_MAX":self.d1_INTERVAL_3_MAX
                                },
                            self.D2_:
                                {
                                    "d2_INTERVAL_1_MAX":self.d2_INTERVAL_1_MAX,
                                    "d2_INTERVAL_2_MAX":self.d2_INTERVAL_2_MAX,
                                    "d2_INTERVAL_3_MAX":self.d2_INTERVAL_3_MAX
                                },
                            self.D3_:
                                {
                                    "d3_INTERVAL_1_MAX":self.d3_INTERVAL_1_MAX,
                                    "d3_INTERVAL_2_MAX":self.d3_INTERVAL_2_MAX,
                                    "d3_INTERVAL_3_MAX":self.d3_INTERVAL_3_MAX

                                },
                            self.AVF_:
                                {
                                    "avf_INTERVAL_1_MAX":self.avf_INTERVAL_1_MAX,
                                    "avf_INTERVAL_2_MAX":self.avf_INTERVAL_2_MAX,
                                    "avf_INTERVAL_3_MAX":self.avf_INTERVAL_3_MAX

                                },
                            self.AVR_:
                                {
                                    "avr_INTERVAL_1_MAX":self.avr_INTERVAL_1_MAX,
                                    "avr_INTERVAL_2_MAX":self.avr_INTERVAL_2_MAX,
                                    "avr_INTERVAL_3_MAX":self.avr_INTERVAL_3_MAX
                                },
                            self.AVL_:
                                {
                                    "avl_INTERVAL_1_MAX":self.avl_INTERVAL_1_MAX,
                                    "avl_INTERVAL_2_MAX":self.avl_INTERVAL_2_MAX,
                                    "avl_INTERVAL_3_MAX":self.avl_INTERVAL_3_MAX,
                                }
                        }

            #Intervalo general
            limit=16
            GENER_INTERVAL=df.query('x >= 236 & x <= 243')
            print(GENER_INTERVAL)
            contPuls=0
            bandera = True


            for index, row in GENER_INTERVAL.iterrows():
                if int(row[self.GENRAL_]) >= limit and bandera==True:
                    contPuls = contPuls + 1
                    bandera = False
                elif  int(row[self.GENRAL_])<limit and bandera == False:
                    contPuls = contPuls + 1
                    bandera = True


            #Graficar valores
            
            

            self.graphicD1.plot(x=df['x'], y=df[self.D1_], pen='#2196F3')

            self.graphicD2.plot(x=(df['x']), y=df[self.D2_], pen='#2196F3')

            self.graphicD3.plot(x=(df['x']), y=df[self.D3_], pen='#2196F3')

            self.graphicD3_2.plot(x=(df['x']), y=df[self.AVF_], pen='#2196F3')

            self.graphicD3_3.plot(x=(df['x']), y=df[self.AVR_], pen='#2196F3')

            self.graphicD3_4.plot(x=(df['x']), y=df[self.AVL_], pen='#2196F3')

            self.graphicsView.plot(x=(df['x']), y=df[self.GENRAL_], pen='#2196F3')

            self.graphicsView.setLabel("bottom", "Time / s")

            self.generatedReport(df,persona,values_ST_T,contPuls/2)
        except NameError:
            print("error: "+NameError)


    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "RECAHOLT"))
        MainWindow.setWindowIcon(QtGui.QIcon('ico.png'))
        self.pushButtonAbrir.setText(_translate("MainWindow", "Open file and report generator"))
        #self.pushButton_2.setText(_translate("MainWindow", "Generar Reporte"))
        self.label_9.setText(_translate("MainWindow", "by Jonathan Recalde"))
        self.label_9.setFont(QtGui.QFont('Times', 20))
        self.label_10.setText(_translate("MainWindow", "RECAHOLT"))
        self.label_10.setFont(QtGui.QFont('Times', 20))
        self.groupBox.setTitle(_translate("MainWindow", "Graphics"))
        self.groupBox.setFont(QtGui.QFont('Times', 20))
        self.label.setText(_translate("MainWindow", "D1"))
        self.label_2.setText(_translate("MainWindow", "D2"))
        self.label_3.setText(_translate("MainWindow", "D3"))
        self.label_4.setText(_translate("MainWindow", "aVF"))
        self.label_5.setText(_translate("MainWindow", "aVR"))
        self.label_6.setText(_translate("MainWindow", "aVL"))
        self.label_nom.setText(_translate("MainWindow", "Name:"))
        self.label_edad.setText(_translate("MainWindow", "Age:"))
        self.label_sexo.setText(_translate("MainWindow", "Gender:"))

        self.graphicD1 = self.graphicD1.addPlot(row=1, col=1)
        self.graphicD2 = self.graphicD2.addPlot(row=1, col=1)
        self.graphicD3 = self.graphicD3.addPlot(row=1, col=1)
        self.graphicD3_2 = self.graphicD3_2.addPlot(row=1, col=1)
        self.graphicD3_3 = self.graphicD3_3.addPlot(row=1, col=1)
        self.graphicD3_4 = self.graphicD3_4.addPlot(row=1, col=1)
        self.graphicsView = self.graphicsView.addPlot(row=1, col=1)



    def generatedReport(self,df,persona,values_ST_T,contPuls):
        #Valores D1
        D1_max= df[self.D1_].max()
        Time_D1=df.query("D1 == '{0}'".format(D1_max))
        int_timeD1= float(Time_D1["x"].values[0])

        ST_D1= values_ST_T[self.D1_]['d1_INTERVAL_1_MAX']
        Time_ST_D1=self.d1_INTERVAL_1.query("D1 == '{0}'".format(ST_D1))
        int_time_ST_D1= float(Time_ST_D1["x"].values[0])

        T_D1= values_ST_T[self.D1_]['d1_INTERVAL_2_MAX']
        Time_T_D1=self.d1_INTERVAL_2.query("D1 == '{0}'".format(T_D1))
        int_time_T_D1= float(Time_T_D1["x"].values[0])

        P_D1= values_ST_T[self.D1_]['d1_INTERVAL_3_MAX']
        Time_P_D1=self.d1_INTERVAL_3.query("D1 == '{0}'".format(P_D1))
        int_time_P_D1= float(Time_P_D1["x"].values[0])
        
        #Valores D2

        D2_max= df[self.D2_].max()
        Time_D2=df.query("D2 == '{0}'".format(D2_max))
        int_timeD2= float(Time_D2["x"].values[0])

        ST_D2= values_ST_T[self.D2_]['d2_INTERVAL_1_MAX']
        Time_ST_D2=self.d2_INTERVAL_1.query("D2 == '{0}'".format(ST_D2))
        int_time_ST_D2= float(Time_ST_D2["x"].values[0])
        
        T_D2= values_ST_T[self.D2_]['d2_INTERVAL_2_MAX']        
        Time_T_D2=self.d2_INTERVAL_2.query("D2 == '{0}'".format(T_D2))
        int_time_T_D2= float(Time_T_D2["x"].values[0])

        P_D2= values_ST_T[self.D2_]['d2_INTERVAL_3_MAX']        
        Time_P_D2=self.d2_INTERVAL_3.query("D2 == '{0}'".format(P_D2))
        int_time_P_D2= float(Time_P_D2["x"].values[0])

        #Valores D3

        D3_max= df[self.D3_].max()
        Time_D3=df.query("D3 == '{0}'".format(D3_max))
        int_timeD3= float(Time_D3["x"].values[0])

        ST_D3= values_ST_T[self.D3_]['d3_INTERVAL_1_MAX']
        Time_ST_D3=self.d3_INTERVAL_1.query("D3 == '{0}'".format(ST_D3))
        int_time_ST_D3= float(Time_ST_D3["x"].values[0])
        
        T_D3= values_ST_T[self.D3_]['d3_INTERVAL_2_MAX']        
        Time_T_D3=self.d3_INTERVAL_2.query("D3 == '{0}'".format(T_D3))
        int_time_T_D3= float(Time_T_D3["x"].values[0])

        P_D3= values_ST_T[self.D3_]['d3_INTERVAL_3_MAX']        
        Time_P_D3=self.d3_INTERVAL_3.query("D3 == '{0}'".format(P_D3))
        int_time_P_D3= float(Time_P_D3["x"].values[0])

        #Valores AVF

        AVF_max= df[self.AVF_].max()
        Time_AVF=df.query("AVF == '{0}'".format(AVF_max))
        int_timeAVF= float(Time_AVF["x"].values[0])

        ST_AVF= values_ST_T[self.AVF_]['avf_INTERVAL_1_MAX']
        Time_ST_AVF=self.avf_INTERVAL_1.query("AVF == '{0}'".format(ST_AVF))
        int_time_ST_AVF= float(Time_ST_AVF["x"].values[0])
        
        T_AVF= values_ST_T[self.AVF_]['avf_INTERVAL_2_MAX']        
        Time_T_AVF=self.avf_INTERVAL_2.query("AVF == '{0}'".format(T_AVF))
        int_time_T_AVF= float(Time_T_AVF["x"].values[0])

        P_AVF= values_ST_T[self.AVF_]['avf_INTERVAL_3_MAX']        
        Time_P_AVF=self.avf_INTERVAL_3.query("AVF == '{0}'".format(P_AVF))
        int_time_P_AVF= float(Time_P_AVF["x"].values[0])

        #Valores AVR

        AVR_max= df[self.AVR_].min()
        Time_AVR=df.query("AVR == '{0}'".format(AVR_max))
        int_timeAVR= float(Time_AVR["x"].values[0])

        ST_AVR= values_ST_T[self.AVR_]['avr_INTERVAL_1_MAX']
        Time_ST_AVR=self.avr_INTERVAL_1.query("AVR == '{0}'".format(ST_AVR))
        int_time_ST_AVR= float(Time_ST_AVR["x"].values[0])
        

        T_AVR= values_ST_T[self.AVR_]['avr_INTERVAL_2_MAX']      
        Time_T_AVR=self.avr_INTERVAL_2.query("AVR == '{0}'".format(T_AVR))
        int_time_T_AVR= float(Time_T_AVR["x"].values[0])

        P_AVR= values_ST_T[self.AVR_]['avr_INTERVAL_3_MAX']      
        Time_P_AVR=self.avr_INTERVAL_3.query("AVR == '{0}'".format(P_AVR))
        int_time_P_AVR= float(Time_P_AVR["x"].values[0])

        #Valores AVL

        AVL_max= df[self.AVL_].max()
        Time_AVL=df.query("AVL == '{0}'".format(AVL_max))
        int_timeAVL= float(Time_AVL["x"].values[0])

        ST_AVL= values_ST_T[self.AVL_]['avl_INTERVAL_1_MAX']
        Time_ST_AVL=self.avl_INTERVAL_1.query("AVL == '{0}'".format(ST_AVL))
        int_time_ST_AVL= float(Time_ST_AVL["x"].values[0])
        
        T_AVL= values_ST_T[self.AVL_]['avl_INTERVAL_2_MAX']        
        Time_T_AVL=self.avl_INTERVAL_2.query("AVL == '{0}'".format(T_AVL))
        int_time_T_AVL= float(Time_T_AVL["x"].values[0])

        P_AVL= values_ST_T[self.AVL_]['avl_INTERVAL_3_MAX']        
        Time_P_AVL=self.avl_INTERVAL_3.query("AVL == '{0}'".format(P_AVL))
        int_time_P_AVL= float(Time_P_AVL["x"].values[0])
        
        # ###################################
        # Content
        try:
            base_path= sys._MEIPASS
        except Exception:
            base_path=os.path.abspath(".")

        path5 = os.path.join(base_path, 'Report.pdf')

        fileName = path5

        documentTitle = 'ECG REPORT'
        title = 'ECG REPORT'
        subTitle = 'Name:'+persona["Nombre"] +" Age:"+persona["Edad"] +" Gender:"+persona["Genero"]

        textLines = [
        'D1 / R:'+str(float(D1_max))+'     ST: '+str(float(ST_D1))+'     T: '+str(float(T_D1))+'     P: '+str(float(P_D1)),
        'Time: '+str(float(int_timeD1)) +'  Time: '+str(float(int_time_ST_D1))+'  Time: '+str(float(int_time_T_D1))+'  Time: '+str(float(int_time_P_D1)),
        'D2 / R:'+str(float(D2_max))+'     ST: '+str(float(ST_D2))+'     T: '+str(float(T_D2)) +'     P: '+str(float(P_D2)),
        'Time: '+str(float(int_timeD2)) +'  Time: '+str(float(int_time_ST_D2))+'  Time: '+str(float(int_time_T_D2))+'  Time: '+str(float(int_time_P_D2)),
        'D3 / R:'+str(float(D3_max))+'     ST: '+str(float(ST_D3))+'     T: '+str(float(T_D3))+'     P: '+str(float(P_D3)),
        'Time: '+str(float(int_timeD3)) +'  Time: '+str(float(int_time_ST_D3))+'  Time: '+str(float(int_time_T_D3))+'  Time: '+str(float(int_time_P_D3)),
        'aVF / R:'+str(float(AVF_max)) +'     ST: '+str(float(ST_AVF))+'     T: '+str(float(T_AVF))+'     P: '+str(float(P_AVF)),
        'Time: '+str(float(int_timeAVF)) +'  Time: '+str(float(int_time_ST_AVF))+'  Time: '+str(float(int_time_T_AVF))+'  Time: '+str(float(int_time_P_AVF)),
        'aVR / R:'+str(float(AVR_max)) +'     ST: '+str(float(ST_AVR))+'     T: '+str(float(T_AVR))+'     P: '+str(float(P_AVR)),
        'Time: '+str(float(int_timeAVR)) +'  Time: '+str(float(int_time_ST_AVR))+'  Time: '+str(float(int_time_T_AVR))+'  Time: '+str(float(int_time_P_AVR)),
        'aVL / R:'+str(float(AVL_max)) +'     ST: '+str(float(T_AVL))+'     T: '+str(float(ST_AVL))+'     P: '+str(float(P_AVL)),
        'Time: '+str(float(int_timeAVL)) +'  Time: '+str(float(int_time_ST_AVL))+'  Time: '+str(float(int_time_T_AVL))+'  Time: '+str(float(int_time_P_AVL)),
        ]
        # ###################################
        # 0) Create document 
        from reportlab.pdfgen import canvas 

        pdf = canvas.Canvas(fileName)
        pdf.setTitle(documentTitle)

        #self.drawMyRuler#(pdf)
        # ###################################
        # 1) Title :: Set fonts 
        # # Print available fonts
        # for font in pdf.getAvailableFonts():
        #     print(font)

        # Register a new font
        from reportlab.pdfbase.ttfonts import TTFont
        from reportlab.pdfbase import pdfmetrics

        try:
            base_path= sys._MEIPASS
        except Exception:
            base_path=os.path.abspath(".")
        


        path4 = os.path.join(base_path, 'SakBunderan.ttf')
        print(path4)


        pdfmetrics.registerFont(
            TTFont('abc', path4)
        )
        pdf.setFont('abc', 36)
        pdf.drawCentredString(300, 770, title)

        # ###################################
        # 2) Sub Title 
        # RGB - Red Green and Blue
        pdf.setFillColorRGB(0, 0, 255)
        pdf.setFont("Courier-Bold", 24)
        pdf.drawCentredString(290,720, subTitle)

        # ###################################
        # 3) Draw a line
        pdf.line(30, 710, 550, 710)

        # ###################################
        # 4) Text object :: for large amounts of text
        from reportlab.lib import colors

        text = pdf.beginText(40, 680)
        text.setFont("Courier", 13)
        text.setFillColor(colors.red)
        val=True
        for line in textLines:
            text.textLine(line)
            if val:
                text.setFillColor(colors.black)
                val=False
            else :
                text.setFillColor(colors.red)
                val=True
                text.textLine("")

        #Valor maximo de X
        value_max_X=float(df["x"].max())/3600
        text.textLine("")
        text.textLine("")
        text.textLine("")
        text.textLine("")
        text.setFillColor(colors.blue)
        truncate = "%.6f" % value_max_X
        text.textLine('Connetion time: '+str(truncate) +" h")
        text.textLine("")
        text.textLine('Heart rate: '+str(round(contPuls)*10) +" bpm")
    

        pdf.drawText(text)
        pdf.save()
class MainUi(QMainWindow):
    def __init__(self):
        super().__init__()

        pg.setConfigOption('background', '#19232D')
        pg.setConfigOption('foreground', 'd')
        pg.setConfigOptions(antialias=True)

        # 窗口居中显示
        self.center()

        self.init_ui()
        # 设置城市的编号
        self.code = ""

        # 多次查询时,查询近5天, 受限于 API 接口提供的数量
        self.num = 5

        # return request json file
        self.rep = ""

        # 创建绘图面板
        self.plt = []
        # 控制绘图的文件名称
        self.filename = 1
        # 默认的状态栏
        # 可以设置其他按钮点击 参考多行文本显示 然而不行
        self.status = self.statusBar()
        self.status.showMessage("我在主页面~")

        # 标题栏
        self.setWindowTitle("天气查询软件")

        self.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5())

    def init_ui(self):

        # self.setFixedSize(960,700)

        # 创建窗口主部件
        self.main_widget = QWidget()
        # 创建主部件的网格布局
        self.main_layout = QGridLayout()
        # 设置窗口主部件布局为网格布局
        self.main_widget.setLayout(self.main_layout)

        # 创建左侧部件
        self.left_widget = QWidget()
        self.left_widget.setObjectName('left_widget')
        # 创建左侧部件的网格布局层
        self.left_layout = QGridLayout()
        # 设置左侧部件布局为网格
        self.left_widget.setLayout(self.left_layout)

        # 创建右侧部件
        self.right_widget = QWidget()
        self.right_widget.setObjectName('right_widget')
        self.right_layout = QGridLayout()
        self.right_widget.setLayout(self.right_layout)

        # 左侧部件在第0行第0列,占8行3列
        self.main_layout.addWidget(self.left_widget, 0, 0, 12, 5)
        # 右侧部件在第0行第3列,占8行9列
        self.main_layout.addWidget(self.right_widget, 0, 5, 12, 7)
        # 设置窗口主部件
        self.setCentralWidget(self.main_widget)

        # function button
        self.single_query = QPushButton("查询今日")
        self.single_query.clicked.connect(self.request_weather)
        self.single_query.setEnabled(False)
        # self.single_query.setFixedSize(400, 30)
        self.btn_tempa = QPushButton("温度预测(可绘图)")
        self.btn_tempa.clicked.connect(self.request_weather)
        self.btn_tempa.setEnabled(False)
        self.btn_wind = QPushButton("风力预测(可绘图)")
        self.btn_wind.clicked.connect(self.request_weather)
        self.btn_wind.setEnabled(False)
        self.btn_stawea = QPushButton("综合天气预测")
        self.btn_stawea.clicked.connect(self.request_weather)
        self.btn_stawea.setEnabled(False)
        self.left_layout.addWidget(self.single_query, 2, 0, 1, 5)
        self.left_layout.addWidget(self.btn_tempa, 3, 0, 1, 5)
        self.left_layout.addWidget(self.btn_wind, 4, 0, 1, 5)
        self.left_layout.addWidget(self.btn_stawea, 5, 0, 1, 5)

        # lineEdit to input a city
        self.city_line = QLineEdit()
        self.city_line.setPlaceholderText("输入城市回车确认")
        self.city_line.returnPressed.connect(self.match_city)
        self.left_layout.addWidget(self.city_line, 1, 0, 1, 5)

        # save figure and quit window
        self.save_fig = QPushButton("保存绘图")
        self.save_fig.setEnabled(False)
        self.save_fig.clicked.connect(self.fig_save)
        self.left_layout.addWidget(self.save_fig, 6, 0, 1, 5)

        self.load = QPushButton("写日记")
        self.left_layout.addWidget(self.load, 7, 0, 1, 5)

        self.quit_btn = QPushButton("退出")
        self.quit_btn.clicked.connect(self.quit_act)
        self.left_layout.addWidget(self.quit_btn, 8, 0, 1, 5)

        # tablewidgt to view data
        self.query_result = QTableWidget()
        self.left_layout.addWidget(self.query_result, 9, 0, 2, 5)
        self.query_result.verticalHeader().setVisible(False)

        self.label = QLabel("预测天气情况绘图展示区")
        self.right_layout.addWidget(self.label, 0, 6, 1, 7)

        self.plot_weather_wind = GraphicsLayoutWidget()
        self.plot_weather_temp = GraphicsLayoutWidget()
        self.right_layout.addWidget(self.plot_weather_temp, 1, 6, 4, 7)
        self.right_layout.addWidget(self.plot_weather_wind, 6, 6, 4, 7)

        self.setWindowOpacity(0.9)  # 设置窗口透明度
        # self.setWindowFlag(QtCore.Qt.FramelessWindowHint) # 隐藏边框
        self.main_layout.setSpacing(0)

    # 按照城市的code, 请求一个城市的天气 返回 json 形式
    def request_weather(self):
        root_url = "http://t.weather.sojson.com/api/weather/city/"
        url = root_url + str(self.code)
        self.rep = get_weather.run(url)
        sender = self.sender()
        if sender.text() == "查询今日":
            self.query(1, 5, '温度', '风向', '风力', 'PM2.5', '天气描述')
        if sender.text() == "温度预测(可绘图)":
            self.btn_tempa.setEnabled(False)
            self.query(self.num, 2, '日期', '温度')
        if sender.text() == "风力预测(可绘图)":
            self.btn_wind.setEnabled(False)
            self.query(self.num, 2, '日期', '风力')
        if sender.text() == "综合天气预测":
            self.query(self.num, 4, '温度', '风向', '风力', '天气描述')

    # 读取 json 文件, 获得城市的code
    def match_city(self):
        # 输入城市后才能点击绘图
        self.btn_tempa.setEnabled(True)
        self.btn_wind.setEnabled(True)
        self.single_query.setEnabled(True)
        self.btn_stawea.setEnabled(True)
        # 在外部json文件中 读取所有城市的 code
        city = read_citycode.read_code("最新_city.json")
        line_city = self.city_line.text()
        # code与输入的城市对比, 如果有, 返回code, 如果没有则默认为北京
        if line_city in city.keys():
            self.code = city[line_city]
        else:
            self.code = "101010100"
            self.city_line.setText("北京")
            Qreply = QMessageBox.about(self, "你犯了一个粗误", "输入城市无效,请示新输入,否则默认为北京")

    # 保存图片成功时的提醒
    def pic_messagebox(self):
        string = '第' + str(self.filename) + '张图片.png'
        Qreply = QMessageBox.information(self, string,
                                         "已经成功保存图片到当前目录, 关闭软件后请及时拷贝走")

    # 保存图片的设置 pyqtgraph 保存无法设置图片路径
    def fig_save(self):
        ex = pe.ImageExporter(self.plt.scene())
        filename = '第' + str(self.filename) + '张图片.png'
        self.filename += 1
        ex.export(fileName=filename)
        self.pic_messagebox()

    def get_date(self, dateFormat="%Y-%m-%d", addDays=0):
        ls = []
        timeNow = datetime.datetime.now()
        key = 0
        if (addDays != 0) and key < addDays - 1:
            for i in range(addDays):
                anotherTime = timeNow + datetime.timedelta(days=key)
                anotherTime.strftime(dateFormat)
                ls.append(str(anotherTime)[0:10])
                key += 1
        else:
            anotherTime = timeNow

        return ls

    # 查询, 可以接受多个参数, 更加灵活的查询
    def query(self, row_num, col_num, *args):
        # true value
        tempature = self.rep.json()['data']['wendu']
        wind_power = self.rep.json()['data']['forecast'][0]['fl']
        wind_direction = self.rep.json()['data']['forecast'][0]['fx']
        pm = self.rep.json()['data']['pm25']
        type_ = self.rep.json()['data']['forecast'][0]['type']
        # forecast value
        pre_tempature = []
        pre_wind_power = []
        pre_wind_direction = []
        pre_pm = []
        pre_type_ = []

        for i in range(self.num):
            pre_tempature.append(
                str(self.rep.json()['data']['forecast'][i]['low']))
            pre_wind_power.append(
                str(self.rep.json()['data']['forecast'][i]['fl']))
            pre_wind_direction.append(
                str(self.rep.json()['data']['forecast'][i]['fx']))
            pre_type_.append(
                str(self.rep.json()['data']['forecast'][i]['type']))

        # 设置当前查询结果的行列
        self.query_result.setRowCount(row_num)
        # 否则不会显示
        self.query_result.setColumnCount(col_num)
        # 表头自适应伸缩
        self.query_result.horizontalHeader().setSectionResizeMode(
            QHeaderView.Stretch)
        # 按照 传入的参数设置表头, 因为每次查询的表头都不一样
        ls = [i for i in args]
        self.query_result.setHorizontalHeaderLabels(ls)

        if col_num > 2 and row_num == 1:
            item = QTableWidgetItem(str(tempature) + "℃")
            # 设置单元格文本颜色
            item.setForeground(QBrush(QColor(144, 182, 240)))
            self.query_result.setItem(0, 0, item)

            item = QTableWidgetItem(str(wind_direction))
            item.setForeground(QBrush(QColor(144, 182, 240)))
            self.query_result.setItem(0, 1, item)

            item = QTableWidgetItem(str(wind_power))
            item.setForeground(QBrush(QColor(144, 182, 240)))
            self.query_result.setItem(0, 2, item)

            item = QTableWidgetItem(str(pm))
            item.setForeground(QBrush(QColor(144, 182, 240)))
            self.query_result.setItem(0, 3, item)

            item = QTableWidgetItem(str(type_))
            item.setForeground(QBrush(QColor(144, 182, 240)))
            self.query_result.setItem(0, 4, item)

        if col_num > 2 and row_num > 1:
            for i in range(0, self.num):
                item = QTableWidgetItem("最" + str(pre_tempature[i]))
                # 设置单元格文本颜色
                item.setForeground(QBrush(QColor(144, 182, 240)))
                self.query_result.setItem(i, 0, item)

                item = QTableWidgetItem(str(pre_wind_direction[i]))
                item.setForeground(QBrush(QColor(144, 182, 240)))
                self.query_result.setItem(i, 1, item)

                item = QTableWidgetItem(str(pre_wind_power[i]))
                item.setForeground(QBrush(QColor(144, 182, 240)))
                self.query_result.setItem(i, 2, item)

                item = QTableWidgetItem(str(pre_type_[i]))
                item.setForeground(QBrush(QColor(144, 182, 240)))
                self.query_result.setItem(i, 3, item)

        if col_num == 2 and row_num > 1:
            date = self.get_date(addDays=self.num)
            key = 0
            for i in date:
                item = QTableWidgetItem(i)
                item.setForeground(QBrush(QColor(144, 182, 240)))
                self.query_result.setItem(key, 0, item)
                key += 1
            if self.query_result.horizontalHeaderItem(1).text() == '温度':
                key = 0
                for i in pre_tempature:
                    item = QTableWidgetItem("最" + i)
                    item.setForeground(QBrush(QColor(144, 182, 240)))
                    self.query_result.setItem(key, 1, item)
                    key += 1
            if self.query_result.horizontalHeaderItem(1).text() == '风力':
                key = 0
                for i in pre_wind_power:
                    item = QTableWidgetItem(i)
                    item.setForeground(QBrush(QColor(144, 182, 240)))
                    self.query_result.setItem(key, 1, item)
                    key += 1

        # 只有两列的时候才可以绘制图像,
        if col_num < 4:
            ls, y = [], []
            x = np.linspace(1, self.num, self.num)
            # 将 treeview 里面的结果以数字的形式返回到列表中, 用于绘图
            for row in range(self.num):
                str1 = str(self.query_result.item(row, 1).text())
                ls.extend(re.findall(r'\d+(?:\.\d+)?', str1))
            if len(ls) == 5:
                y = [float(i) for i in ls]
            if len(ls) == 10:
                lt = [float(i) for i in ls]
                for i in range(0, len(lt), 2):
                    y.append((lt[i] + lt[i + 1]) / 2)
            if len(ls) == 5:
                y = [float(i) for i in ls]
            else:
                y = [float(i) for i in ls[0:5]]
            # 获取 treeview 的标题, 以得到绘图时的标得
            if self.query_result.horizontalHeaderItem(1).text() == '温度':
                title_ = "近期一个月温度变化(预测)"
            if self.query_result.horizontalHeaderItem(1).text() == '风力':
                title_ = "近期一个月风力变化(预测)"
            # 绘图时先清空面板 否则会新加一列,效果不好
            # 且 pyqtgraph 的新加一列有bug, 效果不是很好 下次使用 matplotlib
            if title_ == "近期一个月风力变化(预测)":
                self.plot_weather_wind.clear()
                bg1 = pg.BarGraphItem(x=x,
                                      height=y,
                                      width=0.3,
                                      brush=QColor(137, 232, 165))
                self.plt1 = self.plot_weather_wind.addPlot(title=title_)
                self.plt1.addItem(bg1)
            if title_ == "近期一个月温度变化(预测)":
                self.plot_weather_temp.clear()
                self.plt = self.plot_weather_temp.addPlot(title=title_)
                bg2 = pg.BarGraphItem(x=x,
                                      height=y,
                                      width=0.3,
                                      brush=QColor(32, 235, 233))
                self.plt.addItem(bg2)
            # 绘图后才可以保存图片
            self.save_fig.setEnabled(True)

    # 退出按钮
    def quit_act(self):
        # sender 是发送信号的对象
        sender = self.sender()
        print(sender.text() + '键被按下')
        qApp = QApplication.instance()
        qApp.quit()

    def center(self):
        '''
        获取桌面长宽
        获取窗口长宽
        移动
        '''
        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width() - size.width()) / 2,
                  (screen.height() - size.height()) / 2)
Example #9
0
class ScopeWindow(QtGui.QMainWindow):
    def __init__(self, parent=None, maxepisodes=10):
        super(ScopeWindow, self).__init__(parent)
        self.episodes = None
        self.index = []
        # set a limit on how many episodes to memorize
        self.maxepisodes = maxepisodes
        # Record state of the scope window
        self.isclosed = True
        # This keeps track of the indices of which episodes are loaded
        self._loaded_array = []
        # Default options
        self.options = {'colorfy':False,\
        'layout':[['Voltage', 'A', 0, 0], ['Current', 'A', 1, 0]]} # layout = [Stream, Channel, row, col]
        # Keep track of which colors have been used
        self._usedColors = []
        # Set up the GUI window
        self.setupUi(self)
        self.setDisplayTheme()

    def setupUi(self, MainWindow):
        """This function is converted from the .ui file from the designer"""
        MainWindow.setObjectName(_fromUtf8("Scope Window"))
        MainWindow.resize(1200, 600)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))

        # Graphics layout
        self.horizontalLayout = QtGui.QHBoxLayout(self.centralwidget)
        self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
        self.graphicsLayout = QtGui.QHBoxLayout()
        self.graphicsLayout.setObjectName(_fromUtf8("graphicsLayout"))
        self.graphicsView = GraphicsLayoutWidget(self.centralwidget)
        self.graphicsView.setObjectName(_fromUtf8("graphicsView"))
        self.graphicsLayout.addWidget(self.graphicsView)
        self.horizontalLayout.addLayout(self.graphicsLayout)

        # Side panel layout: initialize as a list view
        self.sideDockPanel = QtGui.QDockWidget("Settings", self)
        self.sideDockPanel.setAllowedAreas(QtCore.Qt.LeftDockWidgetArea | QtCore.Qt.RightDockWidgetArea)
        self.sideDockPanel.setObjectName(_fromUtf8("sideDockPanel"))
        self.sideDockPanel.hide()
        # self.sidePanelLayout = QtGui.QHBoxLayout()
        # self.sidePanelLayout.setObjectName(_fromUtf8("sidePanelLayout"))
        self.listView = QtGui.QListView(self.centralwidget)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.listView.sizePolicy().hasHeightForWidth())
        self.listView.setSizePolicy(sizePolicy)
        self.listView.setObjectName(_fromUtf8("listView"))
        self.sideDockPanel.setWidget(self.listView)
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.sideDockPanel)
        # self.sidePanelLayout.addWidget(self.listView)
        # self.horizontalLayout.addLayout(self.sidePanelLayout)
        MainWindow.setCentralWidget(self.centralwidget)

        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1225, 26))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        self.setMenuBarItems()
        MainWindow.setMenuBar(self.menubar)

        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)

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

    # ---------------- Additional main window behaviors -----------------------
    def setMenuBarItems(self):
        # File Menu
        fileMenu = self.menubar.addMenu('&File')
        # File: Export
        exportMenu = fileMenu.addMenu('&Export')
        exportWithScaleBarAction = QtGui.QAction(QtGui.QIcon('export.png'), 'Export with scalebar', self)
        exportWithScaleBarAction.setShortcut('Ctrl+Alt+E')
        exportWithScaleBarAction.setStatusTip('Export with scalebar')
        exportWithScaleBarAction.triggered.connect(self.printme)
        exportMenu.addAction(exportWithScaleBarAction)

        # View Menu
        viewMenu = self.menubar.addMenu('&View')
        # View: show settings
        viewMenu.addAction(self.sideDockPanel.toggleViewAction())
        # View: Colorfy
        colorfyAction = QtGui.QAction('Color code traces', self, checkable=True, checked=False)
        colorfyAction.setShortcut('Ctrl+Alt+C')
        colorfyAction.setStatusTip('Toggle between color coded traces and black traces')
        colorfyAction.triggered.connect(lambda: self.toggleTraceColors(colorfyAction.isChecked()))
        viewMenu.addAction(colorfyAction)

    def printme(self):
        print('doing stuff')

    def closeEvent(self, event):
        """Override default behavior when closing the main window"""
        self.isclosed = True

    def retranslateUi(self, MainWindow):
        """Set window title and other miscellaneous"""
        MainWindow.setWindowTitle(_translate(__version__, __version__, None))

    # ------------- Episode plotting utilities --------------------------------
    def updateEpisodes(self, episodes=None, index=[]):
        """First compare episodes with self.episodes and index with self.index
        Only update the difference in the two sets"""
        if not isinstance(episodes, dict) or not isinstance(self.episodes, dict):
            bool_old_episode = False
        else:
            bool_old_episode = self.episodes['Name'] == episodes['Name']

        index_insert = list(set(index) - set(self.index))
        index_remove = list(set(self.index) - set(index))

        if bool_old_episode and not index_insert and not index_remove: # same episode, same index
            return
        elif not bool_old_episode: # new item / cell
            index_insert = index
            index_remove = []
            self.episodes = episodes
            self.episodes['Data'] = [[]] * len(self.episodes['Dirs'])
            self._loaded_array = []

        # update index
        self.index += index_insert
        for a in index_remove:
            self.index.remove(a)

        # Insert new episodes
        for i in index_insert:
            self.episodes['Data'][i] = NeuroData(dataFile=self.episodes['Dirs'][i], old=True, infoOnly=False, getTime=True)
            self._loaded_array.append(i)
            # call self.drawPlot
            self.drawEpisode(self.episodes['Data'][i], info=(self.episodes['Name'], self.episodes['Epi'][i]))

        # Remove episodes
        for j in index_remove:
            self.removeEpisode(info=(self.episodes['Name'], self.episodes['Epi'][j]))

    def drawEpisode(self, zData, info=None, pen=None):
        """Draw plot from 1 zData"""
        # Set up pen color
        if self.options['colorfy']:
            availableColors = list(colors)
            for c in self._usedColors:
                availableColors.remove(c)
            pen = availableColors[0]
            self._usedColors.append(pen)
        elif pen is None:
            pen = self.options['theme']['pen']

        # Loop through all the subplots
        for n, l in enumerate(self.options['layout']):
            # get viewbox
            p = self.graphicsView.getItem(row=l[2], col=l[3])
            if p is None:
                p = self.graphicsView.addPlot(row=l[2], col=l[3])
                # Make sure later viewboxes are linked in time domain
                if n>0:
                    p.setXLink(self.graphicsView.getItem(row=0, col=0))

            # put an identifier on the trace
            if isinstance(info, tuple):
                pname = info[0]+'.'+info[1]+'.'+l[0]+'.'+l[1]
            else:
                pname = None

            p.plot(x=zData.Time, y=getattr(zData, l[0])[l[1]], pen=pen, name=pname)


    def removeEpisode(self, info=None):
        if not info:
            return

        for l in self.options['layout']:
            # get viewbox
            p1 = self.graphicsView.getItem(row=l[2], col=l[3])
            pname = info[0]+'.'+info[1]+'.'+l[0]+'.'+l[1]

            remove_index = []
            for k, a in enumerate(p1.listDataItems()):
                if a.name() == pname: # matching
                    p1.removeItem(a)
                    remove_index.append(k)

        # recover the colors
        if remove_index and self.options['colorfy']:
            for r in remove_index:
                del self._usedColors[r]

    # ----------------------- Layout utilities --------------------------------
    def setLayout(self):
        return


    # ----------------------- Option utilities ----------------------------------
    def toggleTraceColors(self, checked):
        """Change traces from black to color coded"""
        # if already painted in color, paint in default pen again
        if not checked:
            self.options['colorfy'] = False
            self._usedColors = [] # reset used colors
        else:
            self.options['colorfy'] = True
        
        for l in self.options['layout']:
            # get viewbox
            p = self.graphicsView.getItem(row=l[2], col=l[3])
            for k, a in enumerate(p.listDataItems()):
                if not checked:
                    pen = self.options['theme']['pen']
                else:
                    pen = colors[k%len(colors)]
                    if pen not in self._usedColors:
                        self._usedColors.append(pen)
                pen = pg.mkPen(pen)
                a.setPen(pen)
        
    def setDisplayTheme(self, theme='whiteboard'):
        self.options['theme'] = {'blackboard':{'background':'k', 'pen':'w'}, \
                 'whiteboard':{'background':'w', 'pen':'k'}\
                }.get(theme)

        self.graphicsView.setBackground(self.options['theme']['background'])
Example #10
0
class Ui_MainWindow(QMainWindow):
    def __init__(self):
        super(Ui_MainWindow, self).__init__()
        self.traindata = []
        self.numberofclasses = 0
        self.trueTestDataLabels = []
        self.labeltestdata = []
        self.testData = []

    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Escape:
            self.close()
        if e.key() == Qt.Key_Delete:
            self.w1.clear()
            classes = []
            i = 0
            while i < 20:
                classes.append([])
                i += 1

            for i in self.traindata:
                classes[i[1]].append(np.asarray(i[0]))
            i = 0
            for j in classes:
                myS = pg.ScatterPlotItem(size=10,
                                         pen=pg.mkPen(colors[i]),
                                         brush=pg.mkBrush(255, 255, 255, 120))
                myspots = []
                if (len(j)):
                    for k in j:
                        myspots.append({'pos': k, 'data': i})
                    i += 1
                    myS.addPoints(myspots)
                    self.w1.addItem(myS)

    def setupUi(self):
        #MainWindow.setObjectName("MainWindow")
        ## MainWindow.setFixedSize
        self.setMinimumSize(QtCore.QSize(754, 603))
        self.setMaximumSize(QtCore.QSize(754, 603))

        self.centralwidget = QtWidgets.QWidget()
        self.centralwidget.setObjectName("centralwidget")
        self.graphicsView = GraphicsLayoutWidget(self.centralwidget)
        self.graphicsView.setGeometry(QtCore.QRect(10, 80, 741, 541))
        self.graphicsView.setObjectName("graphicsView")
        self.widget = QtWidgets.QWidget(self.centralwidget)
        self.widget.setGeometry(QtCore.QRect(10, 10, 740, 62))
        self.widget.setObjectName("widget")
        self.gridLayout = QtWidgets.QGridLayout(self.widget)
        self.gridLayout.setContentsMargins(0, 0, 0, 0)
        self.gridLayout.setObjectName("gridLayout")
        self.loadIrisButton = QtWidgets.QPushButton(self.widget)
        self.loadIrisButton.setObjectName("loadIrisButton")
        self.gridLayout.addWidget(self.loadIrisButton, 0, 0, 1, 2)
        self.checkDateButton = QtWidgets.QPushButton(self.widget)
        self.checkDateButton.setObjectName("checkDateButton")
        self.gridLayout.addWidget(self.checkDateButton, 0, 4, 1, 3)
        self.generateButton = QtWidgets.QPushButton(self.widget)
        self.generateButton.setObjectName("generateButton")
        self.gridLayout.addWidget(self.generateButton, 1, 0, 1, 1)
        self.label_3 = QtWidgets.QLabel(self.widget)
        self.label_3.setObjectName("label_3")
        self.gridLayout.addWidget(self.label_3, 1, 1, 1, 1)
        self.spinBoxClasses = QtWidgets.QSpinBox(self.widget)
        self.spinBoxClasses.setMinimum(2)
        self.spinBoxClasses.setMaximum(8)
        self.spinBoxClasses.setObjectName("spinBoxClasses")
        self.gridLayout.addWidget(self.spinBoxClasses, 1, 2, 1, 1)
        self.label_2 = QtWidgets.QLabel(self.widget)
        self.label_2.setObjectName("label_2")
        self.gridLayout.addWidget(self.label_2, 1, 3, 1, 1)
        self.spinBoxElements = QtWidgets.QSpinBox(self.widget)
        self.spinBoxElements.setMinimum(1)
        self.spinBoxElements.setProperty("value", 20)
        self.spinBoxElements.setObjectName("spinBoxElements")
        self.gridLayout.addWidget(self.spinBoxElements, 1, 4, 1, 1)
        self.label = QtWidgets.QLabel(self.widget)
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 1, 5, 1, 1)
        self.spinBoxK = QtWidgets.QSpinBox(self.widget)
        self.spinBoxK.setMinimum(3)
        self.spinBoxK.setSingleStep(2)
        self.spinBoxK.setObjectName("spinBoxK")
        self.gridLayout.addWidget(self.spinBoxK, 1, 6, 1, 1)

        self.retranslateUi()
        QtCore.QMetaObject.connectSlotsByName(self)
        self.w1 = self.graphicsView.addPlot()
        self.w1.scene().sigMouseClicked.connect(self.onClick)
        self.generateButton.clicked.connect(self.generateDate)
        self.loadIrisButton.clicked.connect(self.loadIris)
        self.checkDateButton.clicked.connect(self.checkTest)
        self.setCentralWidget(self.centralwidget)

    def retranslateUi(self):
        _translate = QtCore.QCoreApplication.translate
        # MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.loadIrisButton.setText(
            _translate("MainWindow", "Загрузить данные с рисом"))
        self.checkDateButton.setText(
            _translate("MainWindow", "Проверить тестовую выборку"))
        self.generateButton.setText(
            _translate("MainWindow", "Сгенерировать выборку"))
        self.label_3.setText(_translate("MainWindow", "Кол-во классов"))
        self.label_2.setText(_translate("MainWindow", "Кол-во элементов"))
        self.label.setText(_translate("MainWindow", "Кол-во соседей(K)"))

    def onClick(self, event):
        if len(self.traindata) == 0:
            return 1
        vb = self.w1.vb
        mousePoint = vb.mapSceneToView(event.scenePos())
        testdata = [[mousePoint.x(), mousePoint.y()]]
        testDataLabels = classifyKNN(self.traindata, testdata,
                                     self.spinBoxK.value(),
                                     self.numberofclasses)
        myS = pg.ScatterPlotItem(size=10,
                                 pen=pg.mkPen(colors[testDataLabels[0]]),
                                 brush=pg.mkBrush(255, 255, 255, 120))
        myspots = []
        myspots.append({
            'pos': np.asarray([mousePoint.x(), mousePoint.y()]),
            'data': testDataLabels[0]
        })
        myS.addPoints(myspots)
        self.w1.addItem(myS)
        self.traindata.append([[mousePoint.x(), mousePoint.y()],
                               testDataLabels[0]])
        print(self.traindata)
        print(mousePoint)

    def loadIris(self):

        with open('train', 'rb') as fp:
            train = pickle.load(fp)
        with open('labels', 'rb') as fp:
            labels = pickle.load(fp)
        self.w1.clear()
        self.numberofclasses = 3
        self.traindata = []
        n = 0
        for i in train:
            self.traindata.append([])
            self.traindata[n].append(i.tolist())
            self.traindata[n].append(labels[n])
            n += 1

        # testDataLabels = classifyKNN(trainData, testData, 5, 2)

        trainData, self.trueTestDataLabels = splitTrainTest(
            self.traindata, 0.33)

        self.traindata = trainData
        self.testData = [
            self.trueTestDataLabels[i][0]
            for i in range(len(self.trueTestDataLabels))
        ]
        self.labeltestdata = classifyKNN(trainData, self.testData,
                                         self.spinBoxK.value(),
                                         self.numberofclasses)

        classes = []
        i = 0
        while i < 20:
            classes.append([])
            i += 1

        for i in self.traindata:
            classes[i[1]].append(np.asarray(i[0]))
        i = 0
        for j in classes:
            myS = pg.ScatterPlotItem(size=10,
                                     pen=pg.mkPen(colors[i]),
                                     brush=pg.mkBrush(255, 255, 255, 120))
            myspots = []
            if (len(j)):
                for k in j:
                    myspots.append({'pos': k, 'data': i})
                i += 1
                myS.addPoints(myspots)
                self.w1.addItem(myS)

    def checkTest(self):
        if len(self.traindata) == 0:
            return 1
        x = sum([
            int(self.labeltestdata[i] == self.trueTestDataLabels[i][1])
            for i in range(len(self.trueTestDataLabels))
        ]) / float(len(self.trueTestDataLabels))
        self.labeltestdata = classifyKNN(self.traindata, self.testData,
                                         self.spinBoxK.value(),
                                         self.numberofclasses)

        classes = []
        i = 0
        while i < 20:
            classes.append([])
            i += 1

        for i in self.trueTestDataLabels:
            classes[i[1]].append(np.asarray(i[0]))
        i = 0
        for j in classes:
            myS = pg.ScatterPlotItem(size=10,
                                     pen=pg.mkPen(colors[i]),
                                     brush=pg.mkBrush(255, 255, 255, 120))
            myspots = []
            if (len(j)):
                for k in j:
                    myspots.append({'pos': k, 'data': i})
                i += 1
                myS.addPoints(myspots)
                self.w1.addItem(myS)

        dialog = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Information,
                                       "Точность классификации ",
                                       str(x),
                                       buttons=QtWidgets.QMessageBox.Ok,
                                       parent=None)
        result = dialog.exec_()

    def changeK(self, i):

        self.spinBoxK.setSingleStep(i)
        self.spinBoxK.setMinimum(i + 1)
        self.spinBoxK.setProperty("value", i + 1)

    def generateDate(self):
        self.w1.clear()
        data = generateData(self.spinBoxElements.value(),
                            self.spinBoxClasses.value())
        self.numberofclasses = self.spinBoxClasses.value()
        trainData, self.trueTestDataLabels = splitTrainTest(data, 0.33)

        self.traindata = trainData
        self.testData = [
            self.trueTestDataLabels[i][0]
            for i in range(len(self.trueTestDataLabels))
        ]
        self.labeltestdata = classifyKNN(trainData, self.testData,
                                         self.spinBoxK.value(),
                                         self.numberofclasses)

        classes = []
        i = 0
        while i < 20:
            classes.append([])
            i += 1

        for i in trainData:
            classes[i[1]].append(np.asarray(i[0]))
        i = 0
        for j in classes:
            myS = pg.ScatterPlotItem(size=10,
                                     pen=pg.mkPen(colors[i]),
                                     brush=pg.mkBrush(255, 255, 255, 120))
            myspots = []
            if (len(j)):
                for k in j:
                    myspots.append({'pos': k, 'data': i})
                i += 1
                myS.addPoints(myspots)
                self.w1.addItem(myS)
Example #11
0
class StockGraph():
    def __init__(self, numofplot=2, name=None, stockInfo=None):
        self.gridContainer = None
        self.dir = None
        self.construct_gridlayout()
        if numofplot < 0:
            print("numofplot must be greater or equal than 0")
            return -1

        if name != None and len(name) > numofplot:
            print("Pls Checking numofplot")
            return -1
        #X-axis data
        self.dataX = None
        self.dataY = None
        self.name = name
        self.stockInfo = stockInfo
        self.graph = GraphicsLayoutWidget()
        self.graph.setObjectName("stock UI")
        self.label = pg.LabelItem(justify='right')
        self.graph.addItem(self.label)
        self.date_axis = TimeAxisItem(orientation='bottom')
        self.date_axis1 = TimeAxisItem(orientation='bottom')

        self.p1 = self.graph.addPlot(row=1,
                                     col=0,
                                     axisItems={'bottom': self.date_axis1})
        #p1 zoom in/out, move viewbox can auto scaling Y, Important!
        self.p1.vb.sigXRangeChanged.connect(self.setYRange)

        self.p2 = self.graph.addPlot(row=2,
                                     col=0,
                                     axisItems={'bottom': self.date_axis})
        #p2 zoom in/out, move viewbox can auto scaling Y. Important!
        self.p2.vb.sigXRangeChanged.connect(self.setYRange)

        # self.p1.showGrid(x=True, y=True, alpha=0.5)
        self.region = pg.LinearRegionItem()
        self.region.setZValue(10)
        # Add the LinearRegionItem to the ViewBox, but tell the ViewBox to exclude this
        # item when doing auto-range calculations.
        self.p2.addItem(self.region, ignoreBounds=True)

        self.p1.setAutoVisible(y=True)

        #cross hair
        self.vLine = pg.InfiniteLine(angle=90, movable=False)
        self.hLine = pg.InfiniteLine(angle=0, movable=False)
        self.p1.addItem(self.vLine, ignoreBounds=True)
        self.p1.addItem(self.hLine, ignoreBounds=True)

        self.vb = self.p1.vb
        self.proxy = pg.SignalProxy(self.p1.scene().sigMouseMoved,
                                    rateLimit=60,
                                    slot=self.mouseMoved)

        #Set PlotDataItem
        self.numofplot = numofplot
        self.name = name
        self.colorStyle = ['r', 'g', 'b', 'y', 'w', 'r']
        self.PlotDataItemList = self.setPlot()
        self.p2_plot = self.p2.plot(name='overview')

        #set gridContainer layout
        self.gridContainer.layout.addWidget(self.graph, 0, 0, 10, 1)
        self.gridContainer.setLayout(self.gridContainer.layout)

        self.calName = ['10avg', '30avg', '90avg']
        self.CalPlotDataItemList = self.setCalPlot()

        #consttuct graph control Panel
        self.construct_controlPanel()

    def construct_gridlayout(self):
        self.gridContainer = QtWidgets.QWidget()
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                           QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHeightForWidth(
            self.gridContainer.sizePolicy().hasHeightForWidth())
        self.gridContainer.setSizePolicy(sizePolicy)
        self.gridContainer.setFocusPolicy(QtCore.Qt.NoFocus)
        self.gridContainer.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
        self.gridContainer.setObjectName("Graphgrid")
        self.gridContainer.layout = QtWidgets.QGridLayout()
        self.gridContainer.setStyleSheet("background-color:black;")

    def construct_controlPanel(self):
        self.maxRadioButton = QtWidgets.QCheckBox("Max")
        self.maxRadioButton.setObjectName("maxRadioButton")
        self.gridContainer.layout.addWidget(self.maxRadioButton, 0, 1, 1, 1)
        self.maxRadioButton.click()
        self.maxRadioButton.setStyleSheet("color: rgb(0, 255, 0);")
        self.maxRadioButton.toggled.connect(
            lambda: self.toggleFunc(self.maxRadioButton, 'high'))

        self.minRadioButton = QtWidgets.QCheckBox("Min")
        self.minRadioButton.setObjectName("minRadioButton")
        self.gridContainer.layout.addWidget(self.minRadioButton, 1, 1, 1, 1)
        self.minRadioButton.click()
        self.minRadioButton.setStyleSheet("color: rgb(255, 255, 255);")
        self.minRadioButton.toggled.connect(
            lambda: self.toggleFunc(self.minRadioButton, 'low'))

        self.closeRadioButton = QtWidgets.QCheckBox("Close")
        self.closeRadioButton.setObjectName("closeRadioButton")
        self.gridContainer.layout.addWidget(self.closeRadioButton, 2, 1, 1, 1)
        self.closeRadioButton.click()
        self.closeRadioButton.setStyleSheet("color: rgb(255,0,0);")
        self.closeRadioButton.toggled.connect(
            lambda: self.toggleFunc(self.closeRadioButton, 'close'))

        self.avg10RadioButton = QtWidgets.QCheckBox("10 AVG")
        self.avg10RadioButton.setObjectName("avg10RadioButton")
        self.gridContainer.layout.addWidget(self.avg10RadioButton, 3, 1, 1, 1)
        self.avg10RadioButton.click()
        self.avg10RadioButton.setStyleSheet("color: rgb(255,255,0);")
        self.avg10RadioButton.toggled.connect(
            lambda: self.toggleFunc(self.avg10RadioButton, '10avg'))

        self.GetButton = QtWidgets.QPushButton("Advance")
        self.GetButton.setObjectName("Advance")
        self.GetButton.clicked.connect(self.Analysis)
        self.GetButton.setStyleSheet("color: rgb(255, 255, 255);")
        self.gridContainer.layout.addWidget(self.GetButton, 4, 1, 1, 1)

    def update_p1_tick(self, minX, maxX, interval=60):
        if self.dataX != None:

            #0 - minX
            lowNum = int(minX / interval)
            #maxX - length
            HighNum = int((len(self.dataX) - 1 - maxX) / interval)

            plotPoint = [(minX - interval * i)
                         for i in range(1, lowNum + 1)] + [minX]
            if (maxX - minX) > interval:
                plotPoint.append(int((maxX + minX) / 2))
            plotPoint = plotPoint + [maxX] + [(maxX + interval * i)
                                              for i in range(1, HighNum + 1)]

            p1_tick = ['' for i in range(0, len(self.dataX))]
            p1_tick = dict(enumerate(p1_tick))
            for index in plotPoint:
                p1_tick[index] = self.dataX[index]

            self.date_axis1.setTicks([list(p1_tick.items())[::1]])

    def update(self):
        self.region.setZValue(10)
        minX, maxX = self.region.getRegion()
        self.p1.setXRange(minX, maxX, padding=0)
        if (maxX < len(self.dataX) - 1):
            self.update_p1_tick(int(minX) + 1, int(maxX))

    def updateRegion(self, window, viewRange):
        rgn = viewRange[0]
        self.region.setRegion(rgn)

    def mouseMoved(self, evt):
        pos = evt[
            0]  ## using signal proxy turns original arguments into a tuple

        if self.p1.sceneBoundingRect().contains(pos):
            mousePoint = self.vb.mapSceneToView(pos)
            index = int(mousePoint.x())

            if index > 0 and index < len(self.dataX):
                idx = int(mousePoint.x())
                self.label.setText(
                    "<span style='font-size: 12pt'>x=%s,   <span style='color: red'>收盤價=%0.1f</span>,   <span style='color: green'>最高價=%0.1f</span>  <span style='color: white'>最低價=%0.1f</span>"
                    % (self.dataX[idx], self.dataY['close'][idx],
                       self.dataY['high'][idx], self.dataY['low'][idx]))
            self.vLine.setPos(mousePoint.x())
            self.hLine.setPos(mousePoint.y())

    def setYRange(self, plotitem):
        plotitem.enableAutoRange(axis='y')
        plotitem.setAutoVisible(y=True)

    def setPlot(self):
        PlotDataItemList = []
        for i in range(0, self.numofplot):
            PlotDataItemList.append(
                self.p1.plot(pen=self.colorStyle[i], name=self.name[i]))
        return PlotDataItemList

    def setCalPlot(self):
        CalPlotDataItemList = []
        for i in range(0, 3):
            CalPlotDataItemList.append(
                self.p1.plot(pen=self.colorStyle[i + 3], name=self.calName[i]))
        return CalPlotDataItemList

    def setData(self, dataX, dataYDict):
        #create numpy arrays
        #make the numbers large to show that the xrange shows data from 10000 to all the way 0
        self.dataX = dataX
        self.dataY = dataYDict
        ticks = dict(enumerate(dataX))
        '''set X-value of P2 and P1'''
        self.date_axis.setTicks(
            [list(ticks.items())[::160],
             list(ticks.items())[::1]])
        self.date_axis1.setTicks(
            [list(ticks.items())[::160],
             list(ticks.items())[::1]])
        '''set Y-value and Plot'''
        for dataY, PlotDataItem in zip(dataYDict.values(),
                                       self.PlotDataItemList):
            PlotDataItem.setData(y=dataY)

        #do not show label
        #self.p1.getAxis('bottom').showLabel(False)

        # self.date_axis.linkToView(self.p1.vb)
        '''set overview data'''
        self.p2_plot.setData(x=list(ticks.keys()),
                             y=dataYDict[self.name[0]],
                             pen="w")
        #set data view range
        self.p2.vb.setLimits(xMin=0, xMax=len(dataYDict[self.name[0]]))
        self.region.sigRegionChanged.connect(self.update)
        # print (self.p2.vb.viewRange())

        # print (self.p1.vb)
        # self.p1.sigRangeChanged.connect(self.updateRegion)

        self.region.setRegion([0, len(dataYDict[self.name[0]])])

        #calculte Data
        avg10 = self.moving_average(dataYDict[self.name[0]], 10)
        self.CalPlotDataItemList[0].setData(y=avg10)

        #make Max and Min are invisiable by default
        self.minRadioButton.setChecked(False)
        self.maxRadioButton.setChecked(False)

    def toggleFunc(self, rdb, name):
        plotItem = None
        for plot in self.PlotDataItemList:
            if plot.name() == name:
                plotItem = plot
        for plot in self.CalPlotDataItemList:
            if plot.name() == name:
                plotItem = plot
        if rdb.isChecked():
            self.p1.addItem(plotItem)
        else:
            self.p1.removeItem(plotItem)

    def setDir(self, dir):
        self.dir = dir

    def Analysis(self):
        d = Dialog(self.dataY, self.dataX, self.dir, self.stockInfo)
        d.exec()

    def ret_GraphicsLayoutWidget(self):
        return self.gridContainer

    @staticmethod
    def removeEvent(self):
        return

    def moving_average(self, data, days):
        result = []
        NanList = [np.nan for i in range(0, days - 1)]
        data = data[:]
        for _ in range(len(data) - days + 1):
            result.append(round(sum(data[-days:]) / days, 2))
            data.pop()
        result = result[::-1]
        return NanList + result
class astraPlotWidget(QWidget):

    twissplotLayout = [
        {
            'name': 'sigma_x',
            'range': [0, 1],
            'scale': 1e3
        },
        {
            'name': 'sigma_y',
            'range': [0, 1],
            'scale': 1e3
        },
        {
            'name': 'kinetic_energy',
            'range': [0, 250],
            'scale': 1e-6
        },
        'next_row',
        {
            'name': 'sigma_p',
            'range': [0, 0.015],
            'scale': 1e6
        },
        {
            'name': 'sigma_z',
            'range': [0, 0.6],
            'scale': 1e3
        },
        {
            'name': 'enx',
            'range': [0.5, 1.5],
            'scale': 1e6
        },
        'next_row',
        {
            'name': 'eny',
            'range': [0.5, 1.5],
            'scale': 1e6
        },
        {
            'name': 'beta_x',
            'range': [0, 150],
            'scale': 1
        },
        {
            'name': 'beta_y',
            'range': [0, 150],
            'scale': 1
        },
    ]

    def __init__(self, directory='.', **kwargs):
        super(astraPlotWidget, self).__init__(**kwargs)
        self.beam = raf.beam()
        self.twiss = rtf.twiss()
        self.directory = directory
        ''' twissPlotWidget '''
        self.twissPlotView = GraphicsView(useOpenGL=True)
        self.twissPlotWidget = GraphicsLayout()
        self.twissPlotView.setCentralItem(self.twissPlotWidget)

        self.latticePlotData = imageio.imread(
            os.path.dirname(os.path.abspath(__file__)) + '/lattice_plot.png')
        self.latticePlots = {}
        self.twissPlots = {}
        i = -1
        for entry in self.twissplotLayout:
            if entry == 'next_row':
                self.twissPlotWidget.nextRow()
            else:
                i += 1
                p = self.twissPlotWidget.addPlot(title=entry['name'])
                p.showGrid(x=True, y=True)
                vb = p.vb
                vb.setYRange(*entry['range'])
                latticePlot = ImageItem(self.latticePlotData)
                latticePlot.setOpts(axisOrder='row-major')
                vb.addItem(latticePlot)
                latticePlot.setZValue(-1)  # make sure this image is on top
                # latticePlot.setOpacity(0.5)
                self.twissPlots[entry['name']] = p.plot(
                    pen=mkPen('b', width=3))
                self.latticePlots[p.vb] = latticePlot
                p.vb.sigRangeChanged.connect(self.scaleLattice)
        ''' beamPlotWidget '''
        self.beamPlotWidget = QWidget()
        self.beamPlotLayout = QVBoxLayout()
        self.beamPlotWidget.setLayout(self.beamPlotLayout)

        #
        # self.beamPlotChoice =
        #

        self.beamPlotAxisWidget = QWidget()
        self.beamPlotAxisWidget.setMaximumHeight(100)
        Form = self.beamPlotAxisWidget

        self.beamPlotXAxisDict = OrderedDict()
        self.beamPlotXAxisDict['x'] = {'scale': 1e3, 'axis': 'x [mm]'}
        self.beamPlotXAxisDict['y'] = {'scale': 1e3, 'axis': 'y [mm]'}
        self.beamPlotXAxisDict['z'] = {
            'scale': 1e6,
            'axis': 'z [micron]',
            'norm': True
        }
        self.beamPlotXAxisDict['t'] = {
            'scale': 1e12,
            'axis': 't [ps]',
            'norm': True
        }
        self.beamPlotXAxisDict['cpx'] = {'scale': 1e3, 'axis': 'cpx [keV]'}
        self.beamPlotXAxisDict['cpy'] = {'scale': 1e3, 'axis': 'cpy [keV]'}
        self.beamPlotXAxisDict['BetaGamma'] = {
            'scale': 0.511,
            'axis': 'cp [MeV]'
        }

        # Form.setObjectName(("Form"))
        # Form.resize(874, 212)
        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(Form.sizePolicy().hasHeightForWidth())
        Form.setSizePolicy(sizePolicy)
        self.horizontalLayout = QHBoxLayout(Form)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.beamPlotXAxisCombo = QComboBox(Form)
        self.beamPlotXAxisCombo.addItems(list(self.beamPlotXAxisDict.keys()))
        self.beamPlotXAxisCombo.setCurrentIndex(2)
        self.horizontalLayout.addWidget(self.beamPlotXAxisCombo)
        self.beamPlotYAxisCombo = QComboBox(Form)
        self.beamPlotYAxisCombo.addItems(list(self.beamPlotXAxisDict.keys()))
        self.beamPlotYAxisCombo.setCurrentIndex(6)
        self.horizontalLayout.addWidget(self.beamPlotYAxisCombo)
        self.groupBox = QGroupBox(Form)
        self.groupBox.setObjectName("groupBox")
        self.formLayout = QFormLayout(self.groupBox)
        self.formLayout.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow)
        self.formLayout.setObjectName("formLayout")
        self.chooseSliceWidth = QRadioButton(self.groupBox)
        self.chooseSliceWidth.setObjectName(("chooseSliceWidth"))
        self.formLayout.setWidget(0, QFormLayout.LabelRole,
                                  self.chooseSliceWidth)
        self.sliceWidth = QDoubleSpinBox(self.groupBox)
        self.sliceWidth.setDecimals(6)
        self.sliceWidth.setObjectName("sliceWidth")
        self.formLayout.setWidget(0, QFormLayout.FieldRole, self.sliceWidth)
        self.chooseSliceNumber = QRadioButton(self.groupBox)
        self.chooseSliceNumber.setChecked(True)
        self.chooseSliceNumber.setObjectName("chooseSliceNumber")
        self.formLayout.setWidget(1, QFormLayout.LabelRole,
                                  self.chooseSliceNumber)
        self.sliceNumber = QSpinBox(self.groupBox)
        self.sliceNumber.setObjectName(("sliceNumber"))
        self.formLayout.setWidget(1, QFormLayout.FieldRole, self.sliceNumber)
        self.horizontalLayout.addWidget(self.groupBox)
        self.chooseSliceWidth.setText(_translate("Form", "Slice Width", None))
        self.chooseSliceNumber.setText(
            _translate("Form", "Number of Slices", None))
        self.sliceWidth.setRange(1e-6, 1)
        self.sliceWidth.setSingleStep(0.00001)
        self.histogramWidth = 0.0005
        self.sliceWidth.setValue(self.histogramWidth)
        # self.sliceNumber = QSpinBox()
        self.sliceNumber.setRange(10, 10000)
        self.sliceNumber.setSingleStep(10)
        self.histogramBins = 100
        self.sliceNumber.setValue(self.histogramBins)

        # self.beamPlotXAxisCombo = QComboBox()

        # self.beamPlotAxisLayout = QHBoxLayout()
        # self.beamPlotAxisWidget.setLayout(self.beamPlotAxisLayout)

        # self.beamPlotAxisLayout.addWidget(self.beamPlotXAxisCombo)
        # self.beamPlotAxisLayout.addWidget(self.beamPlotYAxisCombo)
        # self.beamPlotAxisLayout.addWidget(self.beamPlotNumberBins)
        self.beamPlotXAxisCombo.currentIndexChanged.connect(self.plotDataBeam)
        self.beamPlotYAxisCombo.currentIndexChanged.connect(self.plotDataBeam)
        self.chooseSliceNumber.toggled.connect(self.plotDataBeam)
        self.sliceNumber.valueChanged.connect(self.plotDataBeam)
        self.sliceWidth.valueChanged.connect(self.plotDataBeam)
        # self.beamPlotXAxisCombo.setCurrentIndex(2)
        # self.beamPlotYAxisCombo.setCurrentIndex(5)
        self.canvasWidget = QWidget()
        l = QVBoxLayout(self.canvasWidget)
        self.sc = MyStaticMplCanvas(self.canvasWidget,
                                    width=1,
                                    height=1,
                                    dpi=150)
        l.addWidget(self.sc)
        self.beamPlotLayout.addWidget(self.beamPlotAxisWidget)
        self.beamPlotLayout.addWidget(self.canvasWidget)
        ''' slicePlotWidget '''
        self.sliceParams = [
            {
                'name': 'slice_normalized_horizontal_emittance',
                'units': 'm-rad',
                'text': 'enx'
            },
            {
                'name': 'slice_normalized_vertical_emittance',
                'units': 'm-rad',
                'text': 'eny'
            },
            {
                'name': 'slice_peak_current',
                'units': 'A',
                'text': 'PeakI'
            },
            {
                'name': 'slice_relative_momentum_spread',
                'units': '%',
                'text': 'sigma-p'
            },
            {
                'name': 'slice_beta_x',
                'units': 'm',
                'text': 'beta_x'
            },
            {
                'name': 'slice_beta_y',
                'units': 'm',
                'text': 'beta_y'
            },
        ]
        self.slicePlotWidget = QWidget()
        self.slicePlotLayout = QVBoxLayout()
        self.slicePlotWidget.setLayout(self.slicePlotLayout)
        # self.slicePlotView = GraphicsView(useOpenGL=True)
        self.slicePlotWidgetGraphicsLayout = GraphicsLayoutWidget()
        # self.slicePlots = {}
        self.slicePlotCheckbox = {}
        self.curve = {}
        self.sliceaxis = {}
        self.slicePlotCheckboxWidget = QWidget()
        self.slicePlotCheckboxLayout = QVBoxLayout()
        self.slicePlotCheckboxWidget.setLayout(self.slicePlotCheckboxLayout)
        self.slicePlot = self.slicePlotWidgetGraphicsLayout.addPlot(
            title='Slice', row=0, col=50)
        self.slicePlot.showAxis('left', False)
        self.slicePlot.showGrid(x=True, y=True)
        i = -1
        colors = ['b', 'r', 'g', 'k', 'y', 'm', 'c']
        for param in self.sliceParams:
            i += 1
            axis = AxisItem("left")
            labelStyle = {'color': '#' + colorStr(mkColor(colors[i]))[0:-2]}
            axis.setLabel(text=param['text'],
                          units=param['units'],
                          **labelStyle)
            viewbox = ViewBox()
            axis.linkToView(viewbox)
            viewbox.setXLink(self.slicePlot.vb)
            self.sliceaxis[param['name']] = [axis, viewbox]
            self.curve[param['name']] = PlotDataItem(pen=colors[i], symbol='+')
            viewbox.addItem(self.curve[param['name']])
            col = self.findFirstEmptyColumnInGraphicsLayout()
            self.slicePlotWidgetGraphicsLayout.ci.addItem(axis,
                                                          row=0,
                                                          col=col,
                                                          rowspan=1,
                                                          colspan=1)
            self.slicePlotWidgetGraphicsLayout.ci.addItem(viewbox,
                                                          row=0,
                                                          col=50)
            p.showGrid(x=True, y=True)
            # self.slicePlots[param] = self.slicePlot.plot(pen=colors[i], symbol='+')
            self.slicePlotCheckbox[param['name']] = QCheckBox(param['text'])
            self.slicePlotCheckboxLayout.addWidget(
                self.slicePlotCheckbox[param['name']])
            self.slicePlotCheckbox[param['name']].stateChanged.connect(
                self.plotDataSlice)
        # self.slicePlotView.setCentralItem(self.slicePlotWidgetGraphicsLayout)
        self.slicePlotSliceWidthWidget = QSpinBox()
        self.slicePlotSliceWidthWidget.setMaximum(500)
        self.slicePlotSliceWidthWidget.setValue(100)
        self.slicePlotSliceWidthWidget.setSingleStep(10)
        self.slicePlotSliceWidthWidget.setSuffix(" slices")
        self.slicePlotSliceWidthWidget.setSpecialValueText('Automatic')
        self.slicePlotAxisWidget = QWidget()
        self.slicePlotAxisLayout = QHBoxLayout()
        self.slicePlotAxisWidget.setLayout(self.slicePlotAxisLayout)
        self.slicePlotAxisLayout.addWidget(self.slicePlotCheckboxWidget)
        self.slicePlotAxisLayout.addWidget(self.slicePlotSliceWidthWidget)
        # self.slicePlotXAxisCombo.currentIndexChanged.connect(self.plotDataSlice)
        self.slicePlotSliceWidthWidget.valueChanged.connect(
            self.changeSliceLength)
        # self.beamPlotXAxisCombo.setCurrentIndex(2)
        # self.beamPlotYAxisCombo.setCurrentIndex(5)
        self.slicePlotLayout.addWidget(self.slicePlotAxisWidget)
        self.slicePlotLayout.addWidget(self.slicePlotWidgetGraphicsLayout)

        self.layout = QVBoxLayout()
        self.setLayout(self.layout)

        self.tabWidget = QTabWidget()

        self.folderButton = QPushButton('Select Directory')
        self.folderLineEdit = QLineEdit()
        self.folderLineEdit.setReadOnly(True)
        self.folderLineEdit.setText(self.directory)
        self.reloadButton = QPushButton()
        self.reloadButton.setIcon(qApp.style().standardIcon(
            QStyle.SP_BrowserReload))
        self.folderWidget = QGroupBox()
        self.folderLayout = QHBoxLayout()
        self.folderLayout.addWidget(self.folderButton)
        self.folderLayout.addWidget(self.folderLineEdit)
        self.folderLayout.addWidget(self.reloadButton)
        self.folderWidget.setLayout(self.folderLayout)
        self.folderWidget.setMaximumWidth(800)
        self.reloadButton.clicked.connect(
            lambda: self.changeDirectory(self.directory))
        self.folderButton.clicked.connect(self.changeDirectory)

        self.fileSelector = QComboBox()
        self.fileSelector.currentIndexChanged.connect(self.updateScreenCombo)
        self.screenSelector = QComboBox()
        self.screenSelector.currentIndexChanged.connect(self.changeScreen)
        self.beamWidget = QGroupBox()
        self.beamLayout = QHBoxLayout()
        self.beamLayout.addWidget(self.fileSelector)
        self.beamLayout.addWidget(self.screenSelector)
        self.beamWidget.setLayout(self.beamLayout)
        self.beamWidget.setMaximumWidth(800)
        self.beamWidget.setVisible(False)

        self.folderBeamWidget = QWidget()
        self.folderBeamLayout = QHBoxLayout()
        self.folderBeamLayout.setAlignment(Qt.AlignLeft)
        self.folderBeamWidget.setLayout(self.folderBeamLayout)
        self.folderBeamLayout.addWidget(self.folderWidget)
        self.folderBeamLayout.addWidget(self.beamWidget)

        self.tabWidget.addTab(self.twissPlotView, 'Twiss Plots')
        self.tabWidget.addTab(self.beamPlotWidget, 'Beam Plots')
        self.tabWidget.addTab(self.slicePlotWidget, 'Slice Beam Plots')
        # self.log = lw.loggerWidget()
        # self.log.addLogger(logger)
        # sys.stdout = lw.redirectLogger(self.log, 'stdout')
        # self.tabWidget.addTab(self.log,'Log')
        self.tabWidget.currentChanged.connect(self.changeTab)
        self.layout.addWidget(self.folderBeamWidget)
        self.layout.addWidget(self.tabWidget)

        self.plotType = 'Twiss'
        self.changeDirectory(self.directory)

    def findFirstEmptyColumnInGraphicsLayout(self):
        rowsfilled = list(
            self.slicePlotWidgetGraphicsLayout.ci.rows.get(0, {}).keys())
        for i in range(49):
            if not i in rowsfilled:
                return i

    def changeTab(self, i):
        if self.tabWidget.tabText(i) == 'Beam Plots':
            self.plotType = 'Beam'
            self.beamWidget.setVisible(True)
        elif self.tabWidget.tabText(i) == 'Slice Beam Plots':
            self.plotType = 'Slice'
            self.beamWidget.setVisible(True)
        else:
            self.plotType = 'Twiss'
            self.beamWidget.setVisible(False)
        self.loadDataFile()

    def changeDirectory(self, directory=None):
        self.screenSelector.currentIndexChanged.disconnect(self.changeScreen)
        self.fileSelector.currentIndexChanged.disconnect(
            self.updateScreenCombo)
        if directory == None or directory == False:
            self.directory = str(
                QFileDialog.getExistingDirectory(self, "Select Directory",
                                                 self.directory,
                                                 QFileDialog.ShowDirsOnly))
        else:
            self.directory = directory
        self.folderLineEdit.setText(self.directory)
        self.currentFileText = self.fileSelector.currentText()
        self.currentScreenText = self.screenSelector.currentText()
        self.getScreenFiles()
        self.updateFileCombo()
        self.updateScreenCombo()
        self.loadDataFile()
        self.screenSelector.currentIndexChanged.connect(self.changeScreen)
        self.fileSelector.currentIndexChanged.connect(self.updateScreenCombo)
        self.changeScreen(self.screenSelector.currentIndex())

    def getSposition(self, file):
        file = h5py.File(self.directory + '/' + file + '.hdf5', "r")
        zpos = file.get('/Parameters/Starting_Position')[2]
        if abs(zpos) < 0.01:
            print(zpos, file)
        return zpos

    def getScreenFiles(self):
        self.screenpositions = {}
        files = glob.glob(self.directory + '/*.hdf5')
        filenames = [
            '-'.join(os.path.basename(f).split('-')[:2]) for f in files
        ]
        # print 'filenames = ', filenames
        runnumber = ['001' for f in filenames]
        # print 'runnumber = ', runnumber
        for f, r in list(set(zip(filenames, runnumber))):
            files = glob.glob(self.directory + '/' + f + '*.hdf5')
            screennames = sorted(
                [os.path.basename(s).split('.')[0] for s in files],
                key=lambda x: self.getSposition(x))
            screenpositions = [self.getSposition(s) for s in screennames]
            # print 'screenpositions = ', screenpositions
            self.screenpositions[f] = {
                'screenpositions': screenpositions,
                'screennames': screennames,
                'run': r
            }

    def updateFileCombo(self):
        self.fileSelector.clear()
        i = -1
        screenfirstpos = []
        for f in self.screenpositions:
            if len(self.screenpositions[f]['screenpositions']) > 0:
                screenfirstpos.append(
                    [f, min(self.screenpositions[f]['screenpositions'])])
        screenfirstpos = np.array(screenfirstpos)
        # print 'screenfirstpos = ', screenfirstpos
        sortedscreennames = sorted(screenfirstpos, key=lambda x: float(x[1]))
        print('sortedscreennames = ', sortedscreennames)
        for f in sortedscreennames:
            self.fileSelector.addItem(f[0])
            i += 1
            if f[0] == self.currentFileText:
                self.fileSelector.setCurrentIndex(i)

    def changeScreen(self, i):
        run = self.screenpositions[str(self.fileSelector.currentText())]['run']
        self.beamFileName = str(self.screenpositions[str(
            self.fileSelector.currentText())]['screennames'][
                self.screenSelector.currentIndex()]) + '.hdf5'
        print('beamFileName = ', self.beamFileName)
        self.loadDataFile()

    def updateScreenCombo(self):
        self.screenSelector.clear()
        i = -1
        for i, s in enumerate(self.screenpositions[str(
                self.fileSelector.currentText())]['screennames']):
            self.screenSelector.addItem(
                str(s) + ' (' + str(self.screenpositions[str(
                    self.fileSelector.currentText())]['screenpositions'][i]) +
                ')')
            i += 1
            if s == self.currentScreenText:
                self.screenSelector.setCurrentIndex(i)

    def loadDataFile(self):
        if self.plotType == 'Twiss':
            files = sorted(glob.glob(self.directory + "/*Xemit*"))
            self.twiss.read_astra_emit_files(files)
            files = sorted(glob.glob(self.directory + "/*.flr"))
            self.twiss.read_elegant_twiss_files(files, reset=False)
            self.plotDataTwiss()
        elif self.plotType == 'Beam' or self.plotType == 'Slice':
            if hasattr(
                    self,
                    'beamFileName') and os.path.isfile(self.directory + '/' +
                                                       self.beamFileName):
                # starttime = time.time()
                self.beam.read_HDF5_beam_file(self.directory + '/' +
                                              self.beamFileName)
                # print 'reading file took ', time.time()-starttime, 's'
                # print 'Read file: ', self.beamFileName
                if self.plotType == 'Beam':
                    self.plotDataBeam()
                else:
                    self.changeSliceLength()
                    # self.plotDataSlice()

    def plotDataTwiss(self):
        for entry in self.twissplotLayout:
            if entry == 'next_row':
                pass
            else:
                x = self.twiss['z']
                y = self.twiss[entry['name']] * entry['scale']
                xy = np.transpose(np.array([x, y]))
                x, y = np.transpose(xy[np.argsort(xy[:, 0])])
                self.twissPlots[entry['name']].setData(x=x,
                                                       y=y,
                                                       pen=mkPen('b', width=3))

    def plotDataBeam(self):
        xdict = self.beamPlotXAxisDict[str(
            self.beamPlotXAxisCombo.currentText())]
        ydict = self.beamPlotXAxisDict[str(
            self.beamPlotYAxisCombo.currentText())]
        x = xdict['scale'] * getattr(
            self.beam, str(self.beamPlotXAxisCombo.currentText()))
        if 'norm' in xdict and xdict['norm'] == True:
            x = x - np.mean(x)
        y = ydict['scale'] * getattr(
            self.beam, str(self.beamPlotYAxisCombo.currentText()))
        if 'norm' in ydict and ydict['norm'] == True:
            y = y - np.mean(y)
        if self.chooseSliceWidth.isChecked():
            slices = np.arange(min(x),
                               max(x) + self.sliceWidth.value(),
                               self.sliceWidth.value())
            self.sliceNumber.setValue(len(slices))
            self.sc.plothist(x,
                             y, [slices, len(slices)],
                             xLabel=xdict['axis'],
                             yLabel=ydict['axis'])
        else:
            self.sliceWidth.setValue(
                int(1e6 * ((max(x) - min(x)) / self.sliceNumber.value())) /
                1e6)
            self.sc.plothist(x,
                             y,
                             self.sliceNumber.value(),
                             xLabel=xdict['axis'],
                             yLabel=ydict['axis'])

    def changeSliceLength(self):
        self.beam.slices = self.slicePlotSliceWidthWidget.value()
        self.beam.bin_time()
        self.plotDataSlice()

    def plotDataSlice(self):
        for param in self.sliceParams:
            if self.slicePlotCheckbox[param['name']].isChecked():
                exponent = np.floor(np.log10(np.abs(self.beam.slice_length)))
                x = 10**(12) * np.array(
                    (self.beam.slice_bins - np.mean(self.beam.slice_bins)))
                self.slicePlot.setRange(xRange=[min(x), max(x)])
                # self.plot.setRange(xRange=[-0.5,1.5])
                y = getattr(self.beam, param['name'])
                self.curve[param['name']].setData(x=x, y=y)
                self.sliceaxis[param['name']][0].setVisible(True)
                # currentrange = self.sliceaxis[param['name']][0].range
                # print 'currentrange = ', currentrange
                # self.sliceaxis[param['name']][0].setRange(0, currentrange[1])
            else:
                # pass
                self.curve[param['name']].setData(x=[], y=[])
                self.sliceaxis[param['name']][0].setVisible(False)
            self.sliceaxis[param['name']][1].autoRange()
            currentrange = self.sliceaxis[param['name']][1].viewRange()
            self.sliceaxis[param['name']][1].setYRange(0, currentrange[1][1])

    def scaleLattice(self, vb, range):
        yrange = range[1]
        scaleY = 0.05 * abs(yrange[1] - yrange[0])
        rect = QRectF(0, yrange[0] + 2 * scaleY, 49.2778, 4 * scaleY)
        self.latticePlots[vb].setRect(rect)
Example #13
0
class mainWindow(QMainWindow):
    # Metodo constructor de la clase
    def __init__(self):
        #Inicia el objeto QMainWindow
        QMainWindow.__init__(self)
        #carga la configuracion del archivo .ui en el objeto
        loadUi("mainWindowPPG.ui", self)
        # Loads everything about mainWindowPPG configuration
        self.setupUI()
        # Shared variables, initial values
        self.queue = Queue(N_SAMPLES)
        self.dataR = deque([], maxlen=N_SAMPLES)
        self.dataIR = deque([], maxlen=N_SAMPLES)
        self.TIME = deque([], maxlen=N_SAMPLES)
        self._plt = None
        self._timer_plot = None
        self.plot_colors = ['#0072bd', '#d95319']
        # configures
        self._configure_plot()
        self._configure_timers()
        self._configure_signals()

# Loads everything about mainWindowPPG configuration

    def setupUI(self):
        """
       Configures everything about the mainWindow
        """
        self.plt = GraphicsLayoutWidget(
            self.centralwidget)  # Bringing my plot wiindow as plt
        self.plt.setAutoFillBackground(False)
        self.plt.setStyleSheet("border: 0px;")
        self.plt.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.plt.setFrameShadow(QtWidgets.QFrame.Plain)
        self.plt.setLineWidth(0)
        self.Layout_graphs.addWidget(self.plt, 0, 0, 1,
                                     1)  # Set the plotting squared graph

    def _configure_plot(self):
        """
        Configures specific elements of the PyQtGraph plots.
        :return:
        """
        self.plt.setBackground(background=None)
        self.plt.setAntialiasing(True)
        self._plt = self.plt.addPlot(row=1, col=1)
        self._plt.setLabel('bottom', "Time", "s")
        pass

    def _configure_timers(self):
        """
        Configures specific elements of the QTimers.
        :return:
        """
        self._timer_plot = QtCore.QTimer(
            self)  # gives _timer_plot the attribute of QtCore.QTimer
        self._timer_plot.timeout.connect(
            self._update_plot)  # connects with _update_plot method
        pass

    def _update_plot(self):
        """
        Updates and redraws the graphics in the plot.
        This function us connected to the timeout signal of a QTimer.
        :return:
        """
        # Spo2 signal parameters
        f = 2
        amp1 = 0.5  # amplitud for Sine signal
        zeroDes1 = 0.5413  # Desplacement from zero for Sine signal
        amp2 = 0.5  # amplitud for Cosine signal
        zeroDes2 = 1.5413  # Desplacement from zero for Cosine signal
        # generate the time
        tsignal = time() - self.timestamp
        # Sine signal function
        sR = zeroDes1 + amp1 * 0.8 * np.sin(2 * np.pi * tsignal * 3 * f)
        # Cosine signal function
        sIR = zeroDes2 + amp2 * 0.8 * np.cos(2 * np.pi * tsignal * 3 * f)
        # put the data generate (time & signal) into queue
        self.queue.put([tsignal, sR, sIR])
        # get the data generate into queue
        data = self.queue.get(True, 1)
        # store data into variables
        self.TIME.append(data[0])
        self.dataR.append(data[1])
        self.dataIR.append(data[2])
        # Draw new data
        self._plt.clear()
        self._plt.plot(x=list(self.TIME)[-PLOT_UPDATE_POINTS:],
                       y=list(self.dataR)[-PLOT_UPDATE_POINTS:],
                       pen=self.plot_colors[1])
        self._plt.plot(x=list(self.TIME)[-PLOT_UPDATE_POINTS:],
                       y=list(self.dataIR)[-PLOT_UPDATE_POINTS:],
                       pen=self.plot_colors[0])

    def _configure_signals(self):
        """
        Configures the connections between signals and UI elements.
        :return:
        """
        self.startButton.clicked.connect(self.start)
        self.stopButton.clicked.connect(self.stop)

    def start(self):
        """
        Starts the acquisition of the selected serial port.
        This function is connected to the clicked signal of the Start button.
        :return:
        """
        self.timestamp = time()
        self._timer_plot.start(16)

    def stop(self):
        """
        Stops the acquisition of the selected serial port.
        This function is connected to the clicked signal of the Stop button.
        :return:
        """
        self._timer_plot.stop()  # stop the Qt timer
        self.reset_buffers()  # Go to reset the vector containing values

    def reset_buffers(self):
        self.dataR.clear()
        self.dataIR.clear()
        self.TIME.clear()
Example #14
0
class MainWindow(QWidget):
    _icon = "./docs/20190702211158.jpg"
    _size_of_x = 800
    _size_of_y = 450
    _size_of_profile_x = 300
    _size_of_profile_y = 300

    def __init__(self, user):
        super(MainWindow, self).__init__()

        # user info
        self.user_account_name = "UniversalVoyage"
        self.user_name = "UniversalVoyage"
        self.user_id = "3118113030"
        self.user_gender = "男"
        self.user_room = "413"
        self.user_enter_date = "2020-10-25"
        self.user_unique = "not defined"
        self.profile = "./docs/20190702211158.jpg"
        self._get_user_info(user)
        self.profile = self._get_user_profile(self.user_unique)
        self.ip_address = "not defined"
        self.port = "not defined"

        # make directories for user
        self._make_user_dir()

        # set ICON
        self.Icon = QIcon(self._icon)

        # set sub-window
        self.acquire_win = None
        self.data_manager_win = None
        self.data_sync_win = None
        self.log_win = None
        self.getIP_win = None

        # set label
        self.gender = QLabel(self)
        self.ID = QLabel(self)
        self.username = QLabel(self)
        self.EnterDate = QLabel(self)
        self.Profile = QLabel(self)

        self.HeartRate = QLabel(self)
        self.BloodPressure = QLabel(self)
        self.RespirationRate = QLabel(self)
        self.ECG = QLabel(self)
        self.SpO2 = QLabel(self)
        self.PulseWave = QLabel(self)
        self.Respiration = QLabel(self)
        self.Video = QLabel(self)

        # set data graph
        pg.setConfigOption('background', '#f0f0f0')
        pg.setConfigOption('foreground', 'd')
        pg.setConfigOptions(antialias=True)

        self.central_widget = QtWidgets.QWidget(self)
        self.ECG_graph = GraphicsLayoutWidget(self)
        self.Pulse_graph = GraphicsLayoutWidget(self)
        self.RESP_graph = GraphicsLayoutWidget(self)

        # fake data
        # data = np.loadtxt("./docs/data/yuhang4131130301/ECG/filtered/data332_Channel1_dec.txt")
        # data2 = np.loadtxt("./docs/data/yuhang4131130301/ECG/filtered/data312_Channel1_dec.txt")
        # print(data.shape)
        # print(data2.shape)

        # self.ECG_graph.addPlot(y=data, pen=pg.mkPen(color='b', width=2))
        # self.Pulse_graph.addPlot(y=data, pen=pg.mkPen(color='b', width=2))
        # self.RESP_graph.addPlot(y=data2, pen=pg.mkPen(color='b', width=2))

        self.valueOfHeartRate = QLabel()
        self.valueOfBloodPressure = QLabel()
        self.valueOfRespRate = QLabel()
        self.valueOfSpO2 = QLabel()

        # set button
        self.Acquire = QPushButton()
        self.CheckAndManage = QPushButton()
        self.Synchronize = QPushButton()
        self.Log = QPushButton()
        self.VideoSaving = QPushButton()
        self.Pause = QPushButton()
        self.Stop = QPushButton()
        self.ChangeIP = QPushButton()

        # set layout
        self.vertical_layout = QVBoxLayout()

        self.horizon_top_layout = QHBoxLayout()
        self.vertical_top_left_info_layout = QVBoxLayout()
        self.horizon_top_left_button_layout = QHBoxLayout()
        self.horizon_top_left_profile = QHBoxLayout()
        self.vertical_top_left_layout = QVBoxLayout()
        self.horizon_top_right_layout = QHBoxLayout()
        self.vertical_right_top_left_layout = QVBoxLayout()

        self.vertical_bottom_layout = QVBoxLayout()
        self.horizon_bottom_top_layout_value = QHBoxLayout()
        self.horizon_bottom_left_layout_ECG = QHBoxLayout()
        self.horizon_bottom_left_layout_PW = QHBoxLayout()
        self.horizon_bottom_left_layout_RESP = QHBoxLayout()

        self.video_thread = CameraHandler(self.Video, self.user_name,
                                          self.user_unique)
        self.video_thread.signal.connect(self._slot_video_saving)

        # add item
        self._add_label()
        self._add_button()

        # set layout
        self._set_ui()

    def _set_ui(self):
        """
        set the graph layout
        :return: none
        """

        self.setLayout(self.vertical_layout)
        self.setWindowTitle("欢迎使用!" + self.user_name)

        # desktop = QtWidgets.QApplication.desktop()
        # self._size_of_x = desktop.width()
        # self._size_of_y = desktop.height()

        self.setWindowIcon(self.Icon)
        # self.resize(self._size_of_x, self._size_of_y)
        # print(self._size_of_x.__str__() + " " + self._size_of_y.__str__())
        self.setWindowState(Qt.WindowMaximized)
        # print(self.height())
        print(self.geometry().width(), self.geometry().height())
        # self.setFixedWidth(26)
        # self.setFixedHeight(650)
        # self.setFixedSize(self.width(), self.height())

        # set left-top-mid
        # self.vertical_left_top_right_layout.addStretch(0)
        self.vertical_top_left_info_layout.addWidget(self.username)
        self.vertical_top_left_info_layout.addWidget(self.gender)
        self.vertical_top_left_info_layout.addWidget(self.ID)
        self.vertical_top_left_info_layout.addWidget(self.EnterDate)

        # set left-top-right
        self.horizon_top_left_button_layout.addWidget(self.Acquire)
        # self.horizon_top_left_button_layout.addStretch(0)
        self.horizon_top_left_button_layout.addWidget(self.CheckAndManage)
        # self.horizon_top_left_button_layout.addStretch(0)
        self.horizon_top_left_button_layout.addWidget(self.Synchronize)
        # self.horizon_top_left_button_layout.addStretch(0)
        self.horizon_top_left_button_layout.addWidget(self.ChangeIP)
        # self.horizon_top_left_button_layout.addStretch(0)
        self.horizon_top_left_button_layout.addWidget(self.Log)
        self.horizon_top_left_button_layout.addStretch(0)

        # set left-top
        self.horizon_top_left_profile.addWidget(self.Profile,
                                                alignment=Qt.AlignBottom)
        self.horizon_top_left_profile.addLayout(
            self.vertical_top_left_info_layout)
        self.horizon_top_left_profile.addStretch(0)

        self.vertical_top_left_layout.addLayout(self.horizon_top_left_profile)
        self.vertical_top_left_layout.addLayout(
            self.horizon_top_left_button_layout)

        # set top-right
        self.vertical_right_top_left_layout.addWidget(self.VideoSaving)
        # self.vertical_right_top_left_layout.addStretch(0)
        self.vertical_right_top_left_layout.addWidget(self.Pause)
        # self.vertical_right_top_left_layout.addStretch(0)
        self.vertical_right_top_left_layout.addWidget(self.Stop)

        self.horizon_top_right_layout.addLayout(
            self.vertical_right_top_left_layout)
        self.horizon_top_right_layout.addWidget(self.Video)

        # set top
        self.horizon_top_layout.addLayout(self.vertical_top_left_layout)
        self.horizon_top_layout.addLayout(self.horizon_top_right_layout)

        # set bottom-left
        self.horizon_bottom_top_layout_value.addWidget(self.HeartRate)
        self.horizon_bottom_top_layout_value.addWidget(self.valueOfHeartRate)
        self.horizon_bottom_top_layout_value.addStretch(0)

        self.horizon_bottom_top_layout_value.addWidget(self.BloodPressure)
        self.horizon_bottom_top_layout_value.addWidget(
            self.valueOfBloodPressure)
        self.horizon_bottom_top_layout_value.addStretch(0)

        self.horizon_bottom_top_layout_value.addWidget(self.RespirationRate)
        self.horizon_bottom_top_layout_value.addWidget(self.valueOfRespRate)
        self.horizon_bottom_top_layout_value.addStretch(0)

        self.horizon_bottom_top_layout_value.addWidget(self.SpO2)
        self.horizon_bottom_top_layout_value.addWidget(self.valueOfSpO2)
        self.horizon_bottom_top_layout_value.addStretch(0)
        # self.vertical_bottom_layout.addLayout(self.horizon_bottom_top_layout_value)

        self.horizon_bottom_left_layout_ECG.addWidget(self.ECG)
        self.horizon_bottom_left_layout_ECG.addWidget(self.ECG_graph)
        # self.horizon_bottom_left_layout_ECG.addStretch(0)
        self.vertical_bottom_layout.addLayout(
            self.horizon_bottom_left_layout_ECG)

        self.horizon_bottom_left_layout_PW.addWidget(self.PulseWave)
        self.horizon_bottom_left_layout_PW.addWidget(self.Pulse_graph)
        # self.horizon_bottom_left_layout_PW.addStretch(0)
        self.vertical_bottom_layout.addLayout(
            self.horizon_bottom_left_layout_PW)

        self.horizon_bottom_left_layout_RESP.addWidget(self.Respiration)
        self.horizon_bottom_left_layout_RESP.addWidget(self.RESP_graph)
        # self.horizon_bottom_left_layout_RESP.addStretch(0)
        self.vertical_bottom_layout.addLayout(
            self.horizon_bottom_left_layout_RESP)

        # set the whole layout
        self.vertical_layout.addLayout(self.horizon_top_layout)
        # self.vertical_layout.addStretch(0)
        self.vertical_layout.addLayout(self.horizon_bottom_top_layout_value)
        # self.vertical_layout.addStretch(0)
        self.vertical_layout.addLayout(self.vertical_bottom_layout)

    def _add_button(self):
        """
        set the button to operate the video and the other common function
        :return: none
        """

        # set the font of button
        font_of_button = QFont()
        font_of_button.setFamily('Times')
        font_of_button.setPixelSize(22)

        self.Acquire.setFont(font_of_button)
        self.CheckAndManage.setFont(font_of_button)
        self.Synchronize.setFont(font_of_button)
        self.ChangeIP.setFont(font_of_button)
        self.Log.setFont(font_of_button)
        self.VideoSaving.setFont(font_of_button)
        self.Pause.setFont(font_of_button)
        self.Stop.setFont(font_of_button)

        self.Acquire.setText("数据采集")
        self.CheckAndManage.setText("查看与管理")
        self.Synchronize.setText("数据同步")
        self.ChangeIP.setText("修改IP")
        self.Log.setText("查看报告")
        self.VideoSaving.setText("保存")
        self.Pause.setText("开始")
        self.Stop.setText("暂停")

        self.Acquire.setFixedSize(165, 100)
        self.CheckAndManage.setFixedSize(165, 100)
        self.Synchronize.setFixedSize(165, 100)
        self.ChangeIP.setFixedSize(165, 100)
        self.Log.setFixedSize(165, 100)

        self.VideoSaving.setFixedSize(100, 100)
        self.Pause.setFixedSize(100, 100)
        self.Stop.setFixedSize(100, 100)

        self.Acquire.clicked.connect(self._slot_acquire)
        self.CheckAndManage.clicked.connect(self._slot_data_manager)
        self.Synchronize.clicked.connect(self._slot_get_ip)
        self.Log.clicked.connect(self._slot_log_check)
        self.VideoSaving.clicked.connect(self._slot_video_saving)
        self.Pause.clicked.connect(self._slot_video_start)
        self.ChangeIP.clicked.connect(self._slot_change_ip)

    def _add_label(self):
        """
        labels contain the tips and user's information
        :return: none
        """

        font_of_profile = QFont()
        font_of_profile.setFamily('Times')
        font_of_profile.setPixelSize(55)

        font_of_info = QFont()
        font_of_info.setFamily('Times')
        font_of_info.setPixelSize(35)

        self.Profile.setFont(font_of_profile)
        self.username.setFont(font_of_profile)
        self.gender.setFont(font_of_profile)
        self.ID.setFont(font_of_profile)
        self.EnterDate.setFont(font_of_profile)

        self.HeartRate.setFont(font_of_info)
        self.BloodPressure.setFont(font_of_info)
        self.RespirationRate.setFont(font_of_info)
        self.ECG.setFont(font_of_info)
        self.SpO2.setFont(font_of_info)
        self.PulseWave.setFont(font_of_info)
        self.Respiration.setFont(font_of_info)

        self.valueOfHeartRate.setFont(font_of_info)
        self.valueOfBloodPressure.setFont(font_of_info)
        self.valueOfRespRate.setFont(font_of_info)
        self.valueOfSpO2.setFont(font_of_info)

        self.valueOfHeartRate.setText("--")
        self.valueOfBloodPressure.setText("--")
        self.valueOfRespRate.setText("--")
        self.valueOfSpO2.setText("--")

        # set the text color
        self.HeartRate.setStyleSheet("color:green")
        self.BloodPressure.setStyleSheet("color:green")
        self.RespirationRate.setStyleSheet("color:green")
        self.ECG.setStyleSheet("color:green")
        self.SpO2.setStyleSheet("color:green")
        self.PulseWave.setStyleSheet("color:green")
        self.Respiration.setStyleSheet("color:green")

        self.valueOfHeartRate.setStyleSheet("color:green")
        self.valueOfBloodPressure.setStyleSheet("color:green")
        self.valueOfRespRate.setStyleSheet("color:green")
        self.valueOfSpO2.setStyleSheet("color:green")

        # this will be replaced by the user's image later
        self.Profile.setPixmap(
            QPixmap(self.profile).scaled(self._size_of_profile_x,
                                         self._size_of_profile_y))
        self.username.setText("用户姓名:" + self.user_name)
        self.gender.setText("性别:" + self.user_gender)
        self.ID.setText("身份编号:" + self.user_unique)
        self.EnterDate.setText("入园日期:" + self.user_enter_date)

        # this will be replaced by the video preview later
        self.Video.setFixedSize(720, 400)
        self.Video.setPixmap((QPixmap("./docs/20191012094812.jpg")))

        self.HeartRate.setText("心率:")
        self.BloodPressure.setText("血压:")
        self.RespirationRate.setText("呼吸率:")
        self.ECG.setText("心电:")
        self.SpO2.setText("血氧:")
        self.PulseWave.setText("脉搏:")
        self.Respiration.setText("呼吸:")

    def _get_user_info(self, user):
        """
        get the user's information
        :param user: a list contains the user's information
        :return: none
        """

        if len(user) == 0:
            return
        self.user_account_name = user[0]
        self.user_name = user[2]
        self.user_id = user[3]
        if user[4] == "male":
            self.gender = "男"
        else:
            self.gender = "女"
        self.user_room = user[5]
        date = user[-2]
        self.user_enter_date = date[:4] + "-" + date[4:6] + "-" + date[-2:]
        self.user_unique = user[-1]
        # print(self.user_unique)

    def _get_user_profile(self, unique):
        """
        set the user's profile
        search the profile in the database by user's unique id.
        :param unique: the user's unique id
        :return: the path that stored the user's profile
        """

        if unique == "not defined":
            # print(unique)
            return self._icon
        db = pymysql.connect(host='localhost',
                             user='******',
                             password='******',
                             db='user')
        cursor = db.cursor()
        result = None
        sql = "SELECT * FROM PROFILE WHERE unique_id='%s';" % unique
        try:
            cursor.execute(sql)
            result = cursor.fetchall()
        except Exception as e:
            print(e.__str__())
        # print(len(result))
        if len(result) == 0:
            return self.profile
        return result[0][-1]

    def _slot_acquire(self):
        """
        open the BLE managing window
        :return: none
        """

        self.acquire_win = BLE(self.user_unique)
        self.acquire_win.signal.connect(self._update_data)
        # self.acquire_win = BLEwithBleak()
        self.acquire_win.show()

    def _update_data(self):
        """
        update the recently acquired data
        :return: none
        """

        day = str(time.strftime("%Y%m%d", time.localtime()))
        # set database
        db = None
        # cursor = None
        try:
            db = pymysql.connect(host='localhost',
                                 user='******',
                                 password='******',
                                 db='user')
            # cursor = db.cursor()
        except Exception as e:
            print("database connection wrong" + e.__str__())

        result = None
        try:
            cursor = db.cursor()
            sql = "select * from USERDATA where (unique_id='%s' and date='%s') order by data_number" % \
                  (self.user_unique, day)
            cursor.execute(sql)
            result = cursor.fetchall()
        except Exception as e:
            print("select data wrong" + e.__str__())

        # //-get the data to display
        # //-by the way, this part of code is definite a piece of shit.
        # //-however, I cannot find a more decent way to go.
        mark_ecg = False
        mark_resp = False
        mark_pulse = False
        mark_hr = False
        mark_respr = False
        mark_spo2 = False
        mark_bp = False
        ecg_new = None
        resp_new = None
        pulse_new = None
        hr_new = None
        respr_new = None
        spo2_new = None
        bp_new = None
        for i in range(len(result)):
            if result[i][5] == "ECG" and mark_ecg is not True:
                mark_ecg = True
                ecg_new = np.loadtxt(result[i][6])
            if result[i][5] == "RESP" and mark_resp is not True:
                mark_resp = True
                resp_new = np.loadtxt(result[i][6])
            if result[i][5] == "PULSE" and mark_pulse is not True:
                mark_pulse = True
                pulse_new = np.loadtxt(result[i][6])
            if result[i][5] == "HR" and mark_hr is not True:
                mark_hr = True
                hr_new = result[i][6]
            if result[i][5] == "RESPR" and mark_respr is not True:
                mark_respr = True
                respr_new = result[i][6]
            if result[i][5] == "SPO2" and mark_spo2 is not True:
                mark_spo2 = True
                spo2_new = result[i][6]
            if result[i][5] == "BP" and mark_bp is not True:
                mark_bp = True
                bp_new = result[i][6]

        if mark_ecg:
            self.ECG_graph.addPlot(y=ecg_new, pen=pg.mkPen(color='b', width=2))
        if mark_pulse:
            self.Pulse_graph.addPlot(y=pulse_new,
                                     pen=pg.mkPen(color='b', width=2))
        if mark_resp:
            self.RESP_graph.addPlot(y=resp_new,
                                    pen=pg.mkPen(color='b', width=2))
        if mark_hr:
            self.valueOfHeartRate.setText(hr_new)
        if mark_bp:
            self.valueOfBloodPressure.setText(bp_new)
        if mark_spo2:
            self.valueOfSpO2.setText(spo2_new)
        if mark_respr:
            self.valueOfRespRate.setText(respr_new)
        # //-THE shit is over.

    def _slot_data_manager(self):
        """
        open the Data manager window
        :return: none
        """

        # print(self.user_unique)
        self.data_manager_win = DataManager(self.user_unique)
        self.data_manager_win.show()

    def _slot_data_sync(self):
        """
        open the data synchronizing window
        :return: none
        """

        self.data_sync_win = Synchronize(self.user_unique, self.ip_address,
                                         self.port)
        self.data_sync_win.show()

    def _slot_change_ip(self):
        """
        change the IP address, if the wrong IP was input.
        :return: none
        """

        self.getIP_win = GetIP()
        self.getIP_win.signal.connect(self._slot_set_ip)
        self.getIP_win.show()

    def _slot_get_ip(self):
        """
        get the server's ip address
        :return: none
        """

        if self.ip_address == "not defined" and self.port == "not defined":
            self.getIP_win = GetIP()
            self.getIP_win.signal.connect(self._slot_set_ip)
            self.getIP_win.show()
        else:
            self._slot_data_sync()

    def _slot_set_ip(self, message):
        """
        set the ip address
        :return: none
        """

        self.ip_address = message['ip']
        self.port = message['port']
        print("ip: " + self.ip_address + " port: " + self.port)
        self._slot_data_sync()

    def _slot_log_check(self):
        """
        open the log manager window
        :return: none
        """

        self.log_win = LogManager(self.user_unique)
        self.log_win.show()

    def _slot_video_saving(self):
        """
        save the video and stop the thread.
        :return: none
        """

        if not self.video_thread.setter():
            QMessageBox.information(self, '保存成功!', '视频已保存!', QMessageBox.Ok)
        else:
            QMessageBox.information(self, '保存失败!', '视频未保存!', QMessageBox.Ok)

    def _slot_video_start(self):
        """
        start the video recording.
        :return: none
        """

        if self.video_thread.working:
            # print(1)
            self.video_thread.start()
        else:
            # print(2)
            self.video_thread.setter()
            self.video_thread.start()

    def _make_user_dir(self):
        """
        make the data directories for user
        :return: none
        """

        if self.user_unique == "not defined":
            return

        data = "./docs/data/"
        path = data + self.user_name + self.user_unique + "/"  # user's own dir
        ecg = path + "ECG/"  # ECG
        ecg_original = ecg + "original/"
        ecg_filtered = ecg + "filtered/"
        resp = path + "RESP/"  # respiration
        resp_original = resp + "original/"
        resp_filtered = resp + "filtered/"
        pulse = path + "PULSE/"  # pulse wave
        pulse_original = pulse + "original/"
        pulse_filtered = pulse + "filtered/"
        video = path + "VIDEO/"  # video
        log = path + "LOG"

        if not os.path.exists(path):
            try:
                os.mkdir(path)
            except Exception as e:
                print(e.__str__())

            if not os.path.exists(ecg):
                try:
                    os.mkdir(ecg)
                except Exception as e:
                    print(e.__str__())

            if not os.path.exists(ecg_original):
                try:
                    os.mkdir(ecg_original)
                except Exception as e:
                    print(e.__str__())

            if not os.path.exists(ecg_filtered):
                try:
                    os.mkdir(ecg_filtered)
                except Exception as e:
                    print(e.__str__())

            if not os.path.exists(resp):
                try:
                    os.mkdir(resp)
                except Exception as e:
                    print(e.__str__())

            if not os.path.exists(resp_original):
                try:
                    os.mkdir(resp_original)
                except Exception as e:
                    print(e.__str__())

            if not os.path.exists(resp_filtered):
                try:
                    os.mkdir(resp_filtered)
                except Exception as e:
                    print(e.__str__())

            if not os.path.exists(pulse):
                try:
                    os.mkdir(pulse)
                except Exception as e:
                    print(e)

            if not os.path.exists(pulse_original):
                try:
                    os.mkdir(pulse_original)
                except Exception as e:
                    print(e.__str__())

            if not os.path.exists(pulse_filtered):
                try:
                    os.mkdir(pulse_filtered)
                except Exception as e:
                    print(e.__str__())

            if not os.path.exists(video):
                try:
                    os.mkdir(video)
                except Exception as e:
                    print(e.__str__())

            if not os.path.exists(log):
                try:
                    os.mkdir(log)
                except Exception as e:
                    print(e.__str__())
        else:
            return

    def closeEvent(self, event):
        """
        handle the main window closing event
        :param event: the main window closing event
        :return: none
        """

        question = QMessageBox()
        question.setWindowTitle("退出")
        question.setText("确认要退出吗?")
        question.setIcon(QMessageBox.Question)
        question.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        question.setDefaultButton(QMessageBox.No)
        yes = question.button(QMessageBox.Yes)
        no = question.button(QMessageBox.No)
        yes.setText("确定")
        no.setText("取消")
        question.exec_()
        # //-when the main window is about to close, ask user to choose operation.
        if question.clickedButton() == yes:
            event.accept()
        else:
            event.ignore()
Example #15
0
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
Example #16
0
class AttributeViewer(QWidget):
    """
    Show a scatter plot of two attributes from a set of localizations.

    init
    ----
        locs_path       :   str, path to a CSV with localization 
                            data
        max_spots       :   int, the maximum number of spots to 
                            plot. It's often too costly to render
                            more than 30000 spots or so
        gui_size        :   int
        parent          :   root QWidget

    """
    def __init__(self, locs_path, max_spots=10000, gui_size=600, parent=None):

        super(AttributeViewer, self).__init__(parent=parent)
        self.locs_path = locs_path
        self.max_spots = max_spots
        self.gui_size = gui_size

        self.initData()
        self.initUI()

    def initData(self):
        """
        Load the spots data.

        """
        # Load the locs dataframe
        self.locs = pd.read_csv(self.locs_path).sort_values(by='frame')

        # If too many spots, truncate the dataframe
        if len(self.locs) > self.max_spots:
            print("Truncating dataframe to %d spots" % self.max_spots)
            self.locs = self.locs[:self.max_spots]
        else:
            print("Plotting %d spots" % len(self.locs))

        # List of available attributes to display
        dtypes = [
            'float64', 'float', 'int64', 'int32', 'uint16', 'uint8', 'int'
        ]
        self.parameters = [c for c in self.locs.columns if \
            self.locs[c].dtype in dtypes]

        # Generate colormap
        self.n_colors = 1000
        self.cmap = cm.get_cmap('viridis', self.n_colors)
        self.cmap_hex = np.array([mpl_colors.rgb2hex(self.cmap(i)[:3]) \
            for i in range(self.n_colors)])

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

        """
        # Main window
        self.win = QWidget()
        L = QGridLayout(self.win)
        self.win.resize(self.gui_size * 1.8, self.gui_size)

        # Two subwindows: one on the left for the scatter plot
        # and one on the right for widgets
        self.win_left = QWidget(self.win)
        self.win_right = QWidget(self.win)
        L.addWidget(self.win_left, 0, 0, 1, 3)
        L.addWidget(self.win_right, 0, 3, 1, 1)
        L_left = QGridLayout(self.win_left)
        L_right = QGridLayout(self.win_right)

        # GraphicsLayoutWidget, to organize scatter plot and
        # associated items
        self.graphicsLayoutWidget = GraphicsLayoutWidget(parent=self.win_left)

        # PlotItem, to contain the ScatterPlotItem
        self.plotItem = self.graphicsLayoutWidget.addPlot()
        L_left.addWidget(self.graphicsLayoutWidget, 0, 0)

        # ScatterPlotItem, core data display
        self.scatterPlotItem = ScatterPlotItem(symbol='o',
                                               brush=None,
                                               pxMode=True,
                                               pen={
                                                   'color': '#FFFFFF',
                                                   'width': 4.0
                                               },
                                               size=4.0)
        self.plotItem.addItem(self.scatterPlotItem)

        ## WIDGETS
        widget_align = Qt.AlignTop

        # Select parameter to map to the x-axis
        self.M_par_0 = LabeledQComboBox(self.parameters,
                                        "x-parameter",
                                        init_value="x",
                                        parent=self.win_right)
        L_right.addWidget(self.M_par_0, 0, 0, alignment=widget_align)
        self.M_par_0.assign_callback(self.M_par_callback)

        # Select parameter to map to the y-axis
        self.M_par_1 = LabeledQComboBox(self.parameters,
                                        "y-parameter",
                                        init_value="y",
                                        parent=self.win_right)
        L_right.addWidget(self.M_par_1, 1, 0, alignment=widget_align)
        self.M_par_1.assign_callback(self.M_par_callback)

        # Select which attribute to color the localizations by
        options = self.parameters + ["density"]
        self.M_color_by = LabeledQComboBox(options,
                                           "Color by",
                                           init_value="density",
                                           parent=self.win_right)
        L_right.addWidget(self.M_color_by, 0, 1, alignment=widget_align)
        self.M_color_by.assign_callback(self.M_color_by_callback)

        # Select the size of the window to use when computing
        # localization density
        window_size_options = [
            str(j)
            for j in [3, 5, 7, 9, 11, 13, 15, 19, 23, 31, 41, 61, 81, 101]
        ]
        self.M_density_window = LabeledQComboBox(window_size_options,
                                                 "Density window",
                                                 init_value="7",
                                                 parent=self.win_right)
        L_right.addWidget(self.M_density_window, 1, 1, alignment=widget_align)
        self.M_density_window.assign_callback(self.M_density_window_callback)

        # Button to induce a simpler representation that can handle
        # more spots
        self.simple_mode = False
        self.B_simple = QPushButton("Simple scatter", parent=self.win_right)
        L_right.addWidget(self.B_simple, 2, 0, alignment=widget_align)
        self.B_simple.clicked.connect(self.B_simple_callback)

        # Button to toggle log color scaling
        self.log_scale_mode = True
        self.B_log = QPushButton("Log color scale", parent=self.win_right)
        self.B_log.clicked.connect(self.B_log_callback)
        L_right.addWidget(self.B_log, 2, 1, alignment=widget_align)

        # Empty widgets to manipulate the layout
        n_rows = 15
        for j in range(3, n_rows):
            q = QWidget(self.win_right)
            L_right.addWidget(q, j, 0)

        # Show the main window
        self.update_scatter()
        self.win.show()

    ## CORE FUNCTIONS

    def get_pars(self):
        """
        Get the current attributes mapped to the x and y axes
        of the scatter plot.

        returns
        -------
            (str: x attribute, str: y attribute)

        """
        return self.M_par_0.currentText(), self.M_par_1.currentText()

    def update_scatter(self, rescale=True):
        """
        Update the scatter plot.

        args
        ----
            rescale     :   change axis limits

        """
        cx, cy = self.get_pars()

        # In the special case of plotting x vs y, make sure
        # that the aspect ratio is right
        if ((cx == 'x') and (cy == 'y')) or ((cx == 'y') and (cy == 'x')):
            self.plotItem.setAspectLocked(lock=True)
        else:
            self.plotItem.setAspectLocked(lock=False)

        # Update the scatter plots
        if self.simple_mode:
            self.scatter_simple(cx, cy)
        else:
            self.scatter_color(cx, cy)

        # Set axis labels
        labelStyle = {'font-size': '18pt'}
        self.plotItem.setLabel('bottom', text=cx, **labelStyle)
        self.plotItem.setLabel('left', text=cy, **labelStyle)

        # Change axis limits
        if rescale:
            self.plotItem.autoBtnClicked()

    def scatter_color(self, cx, cy):
        """
        Load the current set of data into a new scatter plot,
        coloring by the current "color by" attribute.

        args
        ----
            cx, cy      :   str, columns in self.locs

        """
        self.scatterPlotItem.setData(size=4.0, brush=None)
        color_attrib = self.M_color_by.currentText()
        if color_attrib == 'density':
            densities, spots = self.make_density(cx, cy)
        else:
            spots = self.make_attrib_colors(color_attrib)
        self.scatterPlotItem.setData(spots=spots)

    def scatter_simple(self, cx, cy):
        """
        A simpler way of representing the data, using black
        and white only.

        args
        ----
            cx, cy  :   str, columns in self.locs

        """
        self.scatterPlotItem.setData(self.locs[cx],
                                     self.locs[cy],
                                     pen=pg.mkPen(None),
                                     brush=pg.mkBrush(255, 255, 255, 10),
                                     size=10)

    def make_density(self, c0, c1):
        """
        Get the normalized density of points along the (c0, c1)
        axis in the set of localizations.

        args
        ----
            c0, c1      :   str, columns in self.locs

        returns
        -------
            (
                1D ndarray, the density of each point;
                dict, argument to pass to ScatterPlotItem.setData
            )

        """
        # Get the current density window size
        w = int(self.M_density_window.currentText())

        # Format the desired two attributes as ndarray for
        # fast indexing
        data = np.asarray(self.locs[[c0, c1]])

        # Each of the attributes could have very different
        # magnitudes, so scale the distances relative to the
        # difference between the 5th and 95th percentiles for
        # each attribute.

        # Special case: x and y get the same scaling
        if ((c0 == 'x') and (c1 == 'y')) or ((c0 == 'y') and (c1 == 'x')):
            ybinsize = 1.0
            xbinsize = 1.0
        else:
            norm = 400.0
            ybinsize = (np.percentile(self.locs[c0], 95) - \
                np.percentile(self.locs[c0], 5)) / norm
            xbinsize = (np.percentile(self.locs[c1], 95) - \
                np.percentile(self.locs[c1], 5)) / norm

        # Create the binning scheme from these bin sizes
        ybinedges = np.arange(np.percentile(self.locs[c0], 0.1),
                              np.percentile(self.locs[c0], 99.9), ybinsize)
        xbinedges = np.arange(np.percentile(self.locs[c1], 0.1),
                              np.percentile(self.locs[c1], 99.9), xbinsize)

        # Bin the data
        H, _yedges, _xedges = np.histogram2d(self.locs[c0],
                                             self.locs[c1],
                                             bins=(ybinedges, xbinedges))

        # Count the number of points in the neighborhood
        # of each point
        density = uniform_filter(H, w)

        # Digitize the data according to the binning scheme
        # X_int = ((data - np.array([ybinedges.min(), xbinedges.min()])) / \
        #     np.array([ybinsize, xbinsize])).astype('int64')
        # data_y_int = X_int[:,0]
        # data_x_int = X_int[:,1]
        data_y_int = np.digitize(data[:, 0], ybinedges)
        data_x_int = np.digitize(data[:, 1], xbinedges)

        # Determine which data points fall within the binning
        # scheme
        inside = (data_y_int>=0) & (data_x_int>=0) & \
            (data_y_int<(len(ybinedges)-1)) & \
            (data_x_int<(len(xbinedges)-1))
        data_y_int_inside = data_y_int[inside]
        data_x_int_inside = data_x_int[inside]

        # Retrieve the densities for each point
        point_densities = np.empty(data.shape[0], dtype=density.dtype)
        point_densities[inside] = density[data_y_int_inside, data_x_int_inside]

        # Set points outside the binning scheme to density 1
        point_densities[~inside] = 1.0

        # Rescale a little
        point_densities = point_densities * (w**2)
        point_densities[point_densities <= 0] = 0.001

        # Log-scale
        if self.log_scale_mode:
            point_densities = np.log(point_densities) / np.log(2.0)
            point_densities[point_densities < 0.0] = 0.0

        # Rescale the point densities into color indices
        R = (point_densities * (self.n_colors - 1) /
             point_densities.max()).astype(np.int64)
        R[~inside] = 0
        spot_colors = self.cmap_hex[R]

        # Format the plotting spot dict
        spots = [{'pos': data[i,:], 'pen': {'color': spot_colors[i], 'width': 3.0}} \
            for i in range(data.shape[0])]

        return point_densities, spots

    def make_attrib_colors(self, attrib):
        """
        Generate a spot format in which the color of each spot
        is keyed to a particular attribute, with appropriate
        rescaling for the different magnitudes of each attribute.

        args
        ----
            attrib  :   str, a column in self.locs

        returns
        -------
            dict, parameters to pass to ScatterPlotItem.setData

        """
        # Current axis attributes
        c0, c1 = self.get_pars()

        # Sort by ascending attribute
        self.locs = self.locs.sort_values(by=attrib)
        XY = np.asarray(self.locs[[c0, c1]])
        Z = np.asarray(self.locs[attrib])

        # Filter out unsanitary values
        sanitary = (~np.isnan(Z)) & (~np.isinf(Z))
        if (~sanitary).any():
            print("Filtering out unsanitary values in %s" % attrib)
        XY = XY[sanitary, :]
        Z = Z[sanitary]

        # Log scale
        if self.log_scale_mode:
            Z[Z <= 0.0] = 0.001
            Z = np.log(Z) / np.log(2.0)

        # Bin localizations by their relative value in
        # the color attribute
        norm = 400.0
        try:
            binsize = (np.percentile(Z, 95) - np.percentile(Z, 5)) / norm
            binedges = np.arange(np.percentile(Z, 0.01),
                                 np.percentile(Z, 99.9), binsize)
            Z[Z < binedges.min()] = binedges.min()
            Z[Z >= binedges.max()] = binedges.max() - binsize
            assignments = np.digitize(Z, bins=binedges).astype('float64')
        except ValueError:
            print("Can't generate a color scale for %s; " \
                "try turning off log scale" % attrib)
            return []

        # Scale into the available color indices
        spot_colors = self.cmap_hex[((assignments * (self.n_colors-1)) / \
            assignments.max()).astype(np.int64)]

        # Generate the argument to ScatterPlotItem.setData
        spots = [{'pos': XY[i,:], 'pen': {'color': spot_colors[i], 'width': 3.0}} \
            for i in range(XY.shape[0])]
        return spots

    ## WIDGET CALLBACKS

    def M_par_callback(self):
        """
        Change the attribute mapped to the axes.

        """
        self.update_scatter(rescale=True)

    def M_color_by_callback(self):
        """
        Change which attribute is used to generate the color
        scheme for the localizations.

        """
        self.update_scatter(rescale=False)

    def M_density_window_callback(self):
        """
        Change the size of the window used to determine the local
        density of each localization in the current plane.

        """
        if self.M_color_by.currentText() == "density":
            self.update_scatter(rescale=False)

    def B_simple_callback(self):
        """
        Change into simple plotting mode, which uses less memory
        to render the plot but doesn't support color.

        """
        self.simple_mode = not self.simple_mode
        self.update_scatter(rescale=False)

    def B_log_callback(self):
        """
        Toggle between log and linear scales for the color map.

        """
        self.log_scale_mode = not self.log_scale_mode
        print("Log scale: ", self.log_scale_mode)
        self.update_scatter(rescale=False)
Example #17
0
class MainUI(object):
    def __init__(self, MainWindow, data_path):

        MainWindow.setWindowTitle('Tracking demo')
        MainWindow.resize(1000, 700)
        # data path
        self.gt_path = data_path
        self.path = data_path

        # Dataset Selection
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox.setGeometry(QtCore.QRect(10, 10, 150, 200))
        self.groupBox.setObjectName("groupBox")

        self.groupBox_legend = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox_legend.setGeometry(QtCore.QRect(10, 220, 200, 300))
        self.groupBox_legend.setObjectName("groupBox_legend")

        # self.legend_label = QtWidgets.QLabel()
        self.legend_label = QtWidgets.QLabel(self.groupBox_legend)
        self.legend_label.setGeometry(QtCore.QRect(10, 20, 95, 20))
        self.legend_label.setText("Ground Trut ----")
        self.legend_label.setStyleSheet(
            " color: rgba(255, 0, 0); font-size: 10pt; font-weight: 300;")

        self.legend_label2 = QtWidgets.QLabel(self.groupBox_legend)
        self.legend_label2.setText("Tracking Result ----")
        self.legend_label2.setStyleSheet(
            " color: rgba(0,255, 0); font-size: 10pt; font-weight: 300;")

        self.radBtn_1 = QtWidgets.QRadioButton(self.groupBox)
        self.radBtn_1.setGeometry(QtCore.QRect(10, 20, 95, 20))
        self.radBtn_1.setObjectName("panda_radBtn")
        self.radBtn_1.toggled.connect(self.setDataset)

        self.radBtn_2 = QtWidgets.QRadioButton(self.groupBox)
        self.radBtn_2.setGeometry(QtCore.QRect(10, 40, 95, 20))
        self.radBtn_2.setObjectName("tiger_radBtn")
        self.radBtn_2.toggled.connect(self.setDataset)

        self.radBtn_3 = QtWidgets.QRadioButton(self.groupBox)
        self.radBtn_3.setGeometry(QtCore.QRect(10, 60, 95, 20))
        self.radBtn_3.setObjectName("panda_radBtn")
        self.radBtn_3.toggled.connect(self.setDataset)

        self.radBtn_4 = QtWidgets.QRadioButton(self.groupBox)
        self.radBtn_4.setGeometry(QtCore.QRect(10, 80, 95, 20))
        self.radBtn_4.setObjectName("tiger_radBtn")
        self.radBtn_4.toggled.connect(self.setDataset)

        self.radBtn_5 = QtWidgets.QRadioButton(self.groupBox)
        self.radBtn_5.setGeometry(QtCore.QRect(10, 100, 95, 20))
        self.radBtn_5.setObjectName("panda_radBtn")
        self.radBtn_5.toggled.connect(self.setDataset)

        self.model_pulldown = QtGui.QComboBox(self.groupBox)
        self.model_pulldown.setGeometry(QtCore.QRect(15, 125, 93, 28))
        self.model_pulldown.setObjectName("model_pulldown")
        # self.model_pulldown.addItem("Select")
        self.model_pulldown.addItem("KCF")
        self.model_pulldown.addItem("MDNet")
        self.model_pulldown.addItem("SiamFC")
        self.img_root = self.path["KCF"]
        self.model_pulldown.activated.connect(self.setModel)

        self.display_Btn = QtWidgets.QPushButton(self.groupBox)
        self.display_Btn.setGeometry(QtCore.QRect(15, 155, 93, 28))
        self.display_Btn.setObjectName("display_Btn")

        # Set up GraphicsLayoutWidget for images
        self.graphicsWindow = GraphicsLayoutWidget(self.centralwidget,
                                                   border=True)
        self.graphicsWindow.setGeometry(QtCore.QRect(140, 10, 850, 600))
        self.graphicsWindow.setObjectName("graphicsWindow")
        MainWindow.setCentralWidget(self.centralwidget)

        self.score_box = self.graphicsWindow.addViewBox(0, 0, colspan=100)
        self.ref_box = self.graphicsWindow.addViewBox(0, 100, colspan=50)

        self.score_box.invertY(
            True)  # Images usually have their Y-axis pointing downward
        self.ref_box.invertY(True)
        self.score_box.setAspectLocked(True)
        self.ref_box.setAspectLocked(True)
        # image stuff
        self.score_map = pg.ImageItem(axisOrder='row-major')
        self.groundtruth_img = pg.ImageItem(axisOrder='row-major')
        self.ref_img = pg.ImageItem(axisOrder='row-major')

        # Set Image placeholders
        self.score_map.setImage(np.zeros((300, 230, 3)))
        self.groundtruth_img.setImage(np.zeros((300, 230, 3)))
        self.ref_img.setImage(np.zeros((300, 230, 3)))

        self.score_box.addItem(self.score_map)

        self.ref_box.addItem(self.ref_img)

        # laybels
        # Add the Labels to the images
        font = QtGui.QFont()
        font.setPointSize(4)

        # parameter for text display
        param_dict = {'color': (255, 255, 255), 'anchor': (0, 1)}
        label_score = pg.TextItem(text='Tracking Result', **param_dict)
        label_gt = pg.TextItem(text='Tracking Error', **param_dict)
        label_ref = pg.TextItem(text='Reference Image', **param_dict)

        font.setPointSize(16)
        label_score.setFont(font)
        label_gt.setFont(font)
        label_ref.setFont(font)
        label_score.setParentItem(self.score_map)
        label_gt.setParentItem(self.groundtruth_img)
        label_ref.setParentItem(self.ref_img)

        self.score_box.addItem(label_score)

        self.ref_box.addItem(label_ref)

        # display buttons
        self.display_Btn.clicked.connect(self.addImages)
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        self.i = 0
        self.error = np.zeros((1))

        self.updateTime = ptime.time()
        self.fps = 0

        # display error plot
        self.error_plot = self.graphicsWindow.addPlot(3, 0, colspan=200)
        self.error_data = np.zeros((3, ))
        self.curve1 = self.error_plot.plot(self.error_data)

        MainWindow.show()

    def exit(self):
        sys.exit()

    def setDataset(self):
        if self.radBtn_1.isChecked():
            self.img_disp_path = "bolt1/"
            self.template_path = "bolt.jpg"
            self.temp_img = self.load_temp()
            self.error_plot.removeItem(self.curve1)
            self.error_data = self.read_error()

        if self.radBtn_2.isChecked():
            self.img_disp_path = "bolt2/"
            self.template_path = "bolt2.jpg"
            self.temp_img = self.load_temp()

            self.error_plot.removeItem(self.curve1)
            self.error_data = self.read_error()

        if self.radBtn_3.isChecked():
            self.img_disp_path = "football/"
            self.template_path = "football.jpg"
            self.temp_img = self.load_temp()
            self.error_plot.removeItem(self.curve1)
            self.error_data = self.read_error()

        if self.radBtn_4.isChecked():
            self.img_disp_path = "football1/"
            self.template_path = "football1.jpg"
            self.temp_img = self.load_temp()
            self.error_plot.removeItem(self.curve1)
            self.error_data = self.read_error()

        if self.radBtn_5.isChecked():
            self.img_disp_path = "mountainbike/"
            self.template_path = "mountainbike.jpg"
            self.temp_img = self.load_temp()
            self.error_plot.removeItem(self.curve1)
            self.error_data = self.read_error()

    def setModel(self):
        if self.model_pulldown.currentText() == "KCF":
            self.error_plot.removeItem(self.curve1)
            self.img_root = self.path["KCF"]
        if self.model_pulldown.currentText() == "MDNet":
            self.error_plot.removeItem(self.curve1)

            self.img_root = self.path["MDNet"]

        if self.model_pulldown.currentText() == "SiamFC":
            self.error_plot.removeItem(self.curve1)
            self.img_root = self.path["SiamFC"]

    def addImages(self, MainWindow):

        self.i = 0

        self.data_set = self.load_data()
        self.error = np.zeros((1))
        self.curve1 = self.error_plot.plot(np.zeros((1, )))
        self.error_plot.removeItem(self.curve1)
        self.curve1 = self.error_plot.plot(np.zeros((1, )))

        self.updateData()

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.groupBox.setTitle(_translate("MainWindow", "Select Dataset"))
        self.radBtn_1.setText(_translate("MainWindow", "Bolt1"))
        self.radBtn_2.setText(_translate("MainWindow", "Bolt2"))

        self.radBtn_3.setText(_translate("MainWindow", "football"))

        self.radBtn_4.setText(_translate("MainWindow", "football1"))
        self.radBtn_5.setText(_translate("MainWindow", "mountainbike"))
        self.display_Btn.setText(_translate("MainWindow", "Display!"))

    def load_temp(self):
        imagePath = os.path.join(self.img_root + self.template_path)
        temp = cv2.imread(imagePath)
        temp = cv2.cvtColor(temp, cv2.COLOR_BGR2RGB)

        return temp

    def load_data(self):
        n_files = len(os.listdir(self.img_root + self.img_disp_path)) - 3
        image_set = []
        for i in range(1, n_files):

            imagePath = os.path.join(self.img_root + self.img_disp_path +
                                     "%08d.jpg" % i)
            frame = cv2.imread(imagePath)  # 1 for colored imaged
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            image_set.append(frame)

        return image_set

    def read_error(self):
        lineList = []

        filePath = os.path.join(self.img_root + self.img_disp_path +
                                "error.txt")
        with open(filePath, 'r') as file:
            for line in file:
                lines = [float(number) for number in line.strip().split()]
                lineList.append(lines[0])
        return np.array(lineList)

    def updateData(self):
        self.score_map.setImage(self.data_set[self.i])
        self.ref_img.setImage(self.temp_img)
        self.i = (self.i + 1) % len(self.data_set)
        now = ptime.time()

        fps2 = 1.0 / (now - self.updateTime)
        self.updateTime = now
        self.fps = self.fps * 0.9 + fps2 * 0.1
        time.sleep(0.01)
        QtCore.QTimer.singleShot(100, self.updateData)

        self.curve1.setData(self.error_data[0:self.i])
class Ui_MainWindow(object):
    def variables(self):
        self.N_ = 'n'
        self.FECHA_ = 'fecha'
        self.HORA_ = 'hora'
        self.TEMPERATURA_ = 'Temp1'
        self.TEMPERATURA2_ = 'Temp2'
        self.TEMPERATURA3_ = 'Temp3'
        self.TEMPERATURA4_ = 'Temp4'

    def setupUi(self, MainWindow):
        try:
            base_path = sys._MEIPASS
        except Exception:
            base_path = os.path.abspath(".")

        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1500, 900)
        #MainWindow.setStyleSheet("background-color: blue;")

        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.pushButtonAbrir = QtWidgets.QPushButton(self.centralwidget)
        self.pushButtonAbrir.setGeometry(QtCore.QRect(800, 25, 300, 42))
        self.pushButtonAbrir.setObjectName("pushButtonAbrir")
        #Label Nombre Empresa
        self.label_nom_empre = QtWidgets.QLabel(self.centralwidget)
        self.label_nom_empre.setGeometry(QtCore.QRect(220, 20, 125, 20))
        self.label_nom_empre.setObjectName("label_nom_empresa")
        #self.label_nom_empre.setFont(QtGui.QFont("Times", 22, QtGui.QFont.Bold))
        #Label Código
        self.label_cod = QtWidgets.QLabel(self.centralwidget)
        self.label_cod.setGeometry(QtCore.QRect(250, 50, 50, 20))
        self.label_cod.setObjectName("label_cod")
        #self.label_cod.setFont(QtGui.QFont("Times", 22, QtGui.QFont.Bold))

        #Caja de Texto Nombre Empresa
        self.line_nom_empre = QtWidgets.QLineEdit(self.centralwidget)
        self.line_nom_empre.resize(200, 32)
        self.line_nom_empre.move(360, 10)
        #Caja de Texto Codigo
        self.line_cod = QtWidgets.QLineEdit(self.centralwidget)
        self.line_cod.resize(200, 32)
        self.line_cod.move(360, 45)

        var_x = 200
        var_y = 830

        #Labels Sensores
        self.label_sensor1 = QtWidgets.QLabel(self.centralwidget)
        self.label_sensor1.setGeometry(
            QtCore.QRect(var_x + 220, var_y, 150, 20))
        self.label_sensor1.setObjectName("label_sensor1")
        self.label_sensor1.setFont(QtGui.QFont("Times", 22, QtGui.QFont.Bold))
        self.label_sensor1.setStyleSheet('color: blue')

        self.label_sensor2 = QtWidgets.QLabel(self.centralwidget)
        self.label_sensor2.setGeometry(
            QtCore.QRect(var_x + 380, var_y, 150, 20))
        self.label_sensor2.setObjectName("label_sensor2")
        self.label_sensor2.setFont(QtGui.QFont("Times", 22, QtGui.QFont.Bold))
        self.label_sensor2.setStyleSheet('color: yellow')

        self.label_sensor3 = QtWidgets.QLabel(self.centralwidget)
        self.label_sensor3.setGeometry(
            QtCore.QRect(var_x + 540, var_y, 150, 20))
        self.label_sensor3.setObjectName("label_sensor3")
        self.label_sensor3.setFont(QtGui.QFont("Times", 22, QtGui.QFont.Bold))
        self.label_sensor3.setStyleSheet('color: red')

        self.label_sensor4 = QtWidgets.QLabel(self.centralwidget)
        self.label_sensor4.setGeometry(
            QtCore.QRect(var_x + 700, var_y, 150, 20))
        self.label_sensor4.setObjectName("label_sensor4")
        self.label_sensor4.setFont(QtGui.QFont("Times", 22, QtGui.QFont.Bold))
        self.label_sensor4.setStyleSheet('color: green')

        self.label_promedio = QtWidgets.QLabel(self.centralwidget)
        self.label_promedio.setGeometry(
            QtCore.QRect(var_x + 860, var_y, 150, 20))
        self.label_promedio.setObjectName("label_promedio")
        self.label_promedio.setFont(QtGui.QFont("Times", 22, QtGui.QFont.Bold))
        self.label_promedio.setStyleSheet('color: brown')

        self.graphicsView = GraphicsLayoutWidget(self.centralwidget)
        self.graphicsView.setGeometry(QtCore.QRect(100, 100, 1300, 700))
        self.graphicsView.setObjectName("graphicsView")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 100, 22))
        self.menubar.setObjectName("menubar")

        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.pushButtonAbrir.clicked.connect(self.mybutton_clicked)
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def mybutton_clicked(self, MainWindow):
        try:

            msg = QMessageBox()
            msg.setWindowTitle("Alerta")
            if self.line_nom_empre.text() == '' or self.line_cod.text() == '':
                msg.setText("Por favor ingreso los campos requeridos")
                x = msg.exec_()
            else:
                #Nombre de encabezados del archivo CSV
                self.variables()
                filename = QtWidgets.QFileDialog.getOpenFileName()
                if filename[0] != '':
                    dirReport = os.path.dirname(filename[0])
                    df = pandas.read_csv(filename[0])
                    #Graficar valores
                    const = df['Hora'][0]
                    tiempo_aux = []
                    format = '%H:%M:%S'
                    promedio = []
                    for index, row in df.iterrows():
                        diff = (datetime.strptime(str(row['Hora']), format) -
                                datetime.strptime(str(const), format)) / 60
                        total_minu = round(diff.total_seconds(), 1)
                        tiempo_aux.append(total_minu)
                        var_promedio = (row['Temp1'] + row['Temp2'] +
                                        row['Temp3'] + row['Temp4']) / 4
                        promedio.append(var_promedio)

                    x = tiempo_aux
                    y = df[self.TEMPERATURA_]
                    y2 = df[self.TEMPERATURA2_]
                    y3 = df[self.TEMPERATURA3_]
                    y4 = df[self.TEMPERATURA4_]
                    y5 = promedio
                    self.graphicsView.plot(x, y, pen='#2196F3')
                    self.graphicsView.plot(x, y2, pen='#eff321')
                    self.graphicsView.plot(x, y3, pen='#f32121')
                    self.graphicsView.plot(x, y4, pen='#21f340')
                    self.graphicsView.plot(x, y5, pen='#b97d33')
                    self.graphicsView.setLabel(
                        "bottom",
                        "X = Tiempo (Minutos) / Y = Grados (Centigrados)")
                    #Generar reporte
                    self.generatedReport(df, dirReport)
                else:
                    msg.setText("Por favor seleccionar el archivo CSV")
                    x = msg.exec_()

        except Exception as e:
            msg.setText("Por favor seleccione el archivo correcto")
            x = msg.exec_()
            print(e)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "TEMPERATURA"))
        MainWindow.setWindowIcon(QtGui.QIcon('ico.png'))
        self.pushButtonAbrir.setText(
            _translate("MainWindow", "Abrir archivo y generar reporte"))
        self.graphicsView = self.graphicsView.addPlot(row=1, col=1)
        self.label_cod.setText(_translate("MainWindow", "Código:"))
        self.label_nom_empre.setText(
            _translate("MainWindow", "Nombre de Empresa:"))
        self.label_sensor1.setText(
            _translate("MainWindow", "--- Sensor #1 ---"))
        self.label_sensor2.setText(
            _translate("MainWindow", "--- Sensor #2 ---"))
        self.label_sensor3.setText(
            _translate("MainWindow", "--- Sensor #3 ---"))
        self.label_sensor4.setText(
            _translate("MainWindow", "--- Sensor #4 ---"))
        self.label_promedio.setText(
            _translate("MainWindow", "--- Promedio ---"))

    def generatedReport(self, df, dirReport):

        #Valores de cajas de texto
        nom_empre = self.line_nom_empre.text()
        codigo_text = self.line_cod.text()

        #Image

        #pdfmetrics.registerFont(TTFont('chsFont', 'STHeiti Light.ttc'))
        stylesheet = getSampleStyleSheet()

        elements = []
        try:
            base_path = sys._MEIPASS
        except Exception:
            base_path = os.path.abspath(".")

        fecha = str(datetime.today().strftime('%Y-%m-%d'))

        address = "Reporte_" + fecha + "_.pdf"
        path = os.path.join(dirReport, address)

        path2 = os.path.join(base_path, "cap.jpeg")

        doc = SimpleDocTemplate(path)

        #Imagen
        elements.append(Image(path2, width=1 * inch, height=1 * inch))

        #Titulo
        elements.append(
            Paragraph('<font >REPORTE DE TEMPERATURA</font>',
                      stylesheet['Title']))

        #Descripcion
        elements.append(
            Paragraph('<font >DATOS GENERALES</font>', stylesheet['BodyText']))
        elements.append(
            Paragraph(
                '<font >Empresa: ' + nom_empre +
                '</font> <font >         Código:  ' + codigo_text + '</font>',
                stylesheet['BodyText']))
        elements.append(
            Paragraph('<font >Fecha:  ' + fecha + '</font>',
                      stylesheet['BodyText']))
        elements.append(Paragraph('<font ></font>', stylesheet['BodyText']))

        #Descripcion Ejes
        elements.append(
            Paragraph('<font >DESCRIPCIÓN GRÁFICO</font>',
                      stylesheet['BodyText']))
        elements.append(
            Paragraph(
                '<font >      Eje Y = Grados Centigrados / Eje X = Tiempo Minutos</font>',
                stylesheet['BodyText']))
        elements.append(
            Paragraph(
                '<font color=blue>        -- Sensor #1 --</font> <font color=yellow>-- Sensor #2 --</font> <font color=red>-- Sensor #3 --</font> <font color=green>-- Sensor #4 --</font> <font color=brown>-- Promedio --</font>',
                stylesheet['BodyText']))
        elements.append(Spacer(1, 1 * inch))

        #Datos para el Gráfico

        lista_temp1 = []
        lista_temp2 = []
        lista_temp3 = []
        lista_temp4 = []
        lista_total = []
        promedio_ = []

        data_table = []
        cabecera = []
        cabecera.append('No')
        cabecera.append('Fecha')
        cabecera.append('Hora')
        cabecera.append('Temp 1')
        cabecera.append('Temp 2')
        cabecera.append('Temp 3')
        cabecera.append('Temp 4')
        cabecera.append('Tiempo / Minutos')
        cabecera.append('Promedio')
        data_table.append(cabecera)

        const = df['Hora'][0]

        format = '%H:%M:%S'
        for index, row in df.iterrows():
            diff = (datetime.strptime(str(row['Hora']), format) -
                    datetime.strptime(str(const), format)) / 60
            total_minu = round(diff.total_seconds(), 1)

            var_promedio = (row['Temp1'] + row['Temp2'] + row['Temp3'] +
                            row['Temp4']) / 4
            round_promedio = round(var_promedio, 2)
            c_1 = (total_minu, row['Temp1'])
            c_2 = (total_minu, row['Temp2'])
            c_3 = (total_minu, row['Temp3'])
            c_4 = (total_minu, row['Temp4'])
            c_5 = (total_minu, round_promedio)
            lista_temp1.append(c_1)
            lista_temp2.append(c_2)
            lista_temp3.append(c_3)
            lista_temp4.append(c_4)
            promedio_.append(c_5)
            array_aux = []
            array_aux.append(row['n'])
            array_aux.append(row['Fecha'])
            array_aux.append(row['Hora'])
            array_aux.append(row['Temp1'])
            array_aux.append(row['Temp2'])
            array_aux.append(row['Temp3'])
            array_aux.append(row['Temp4'])
            array_aux.append(total_minu)
            array_aux.append(round_promedio)
            data_table.append(array_aux)

        lista_total.append(lista_temp1)
        lista_total.append(lista_temp2)
        lista_total.append(lista_temp3)
        lista_total.append(lista_temp4)
        lista_total.append(promedio_)

        elements.append(Spacer(1, 1 * inch))
        elements.append(Spacer(1, 1 * inch))

        drawing = Drawing(400, 200)
        lp = LinePlot()
        lp.x = 100
        lp.y = 100
        lp.height = 300
        lp.width = 300
        lp.data = lista_total
        lp.joinedLines = 1
        #lp.lineLabelFormat = '%2.0f'
        lp.strokeColor = colors.black
        lp.xValueAxis.valueMin = 0
        lp.xValueAxis.valueMax = 100
        lp.xValueAxis.valueStep = 10
        #lp.xValueAxis.valueSteps =listHora_aux
        lp.xValueAxis.labelTextFormat = '%2.1f'
        lp.yValueAxis.valueMin = 0
        lp.yValueAxis.valueMax = 180
        lp.yValueAxis.valueStep = 5
        lp.lines[0].strokeColor = colors.blue
        lp.lines[1].strokeColor = colors.yellow
        lp.lines[2].strokeColor = colors.red
        lp.lines[3].strokeColor = colors.green
        lp.lines[4].strokeColor = colors.brown

        drawing.add(lp)

        elements.append(drawing)

        #Tabla
        elements.append(
            Paragraph('<font >DESCRIPCIÓN TABLA</font>',
                      stylesheet['BodyText']))
        elements.append(Paragraph('<font ></font>', stylesheet['BodyText']))

        style_table = TableStyle([
            ('BACKGROUND', (0, 0), (8, 0), colors.green),
            ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
            ('ALIGN', (0, 0), (8, 1000000), 'CENTER'),
            ('FONTNAME', (0, 0), (-1, 0), 'Courier-Bold')
        ])

        table = Table(data_table)
        table.setStyle(style_table)
        elements.append(table)

        elements.append(Spacer(1, 1 * inch))
        elements.append(Spacer(1, 1 * inch))

        #Firma
        #elements.append(Paragraph('<font >Hola</font>', stylesheet['Title']))
        elements.append(Spacer(1, 1 * inch))

        doc.build(elements)
        msg = QMessageBox()
        msg.setWindowTitle("Alerta")
        msg.setText("Correcta Generación de Reporte !!!")
        x = msg.exec_()
Example #19
0
class Dialog(QtGui.QDialog):
    def __init__(self,
                 dataY=None,
                 dataX=None,
                 dir=None,
                 stockInfo=None,
                 parent=None):
        super(Dialog, self).__init__(parent)
        self.resize(800, 800)
        self.gridContainer = None
        self.gridContainer = QtWidgets.QWidget(self)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                           QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHeightForWidth(
            self.gridContainer.sizePolicy().hasHeightForWidth())
        self.gridContainer.setSizePolicy(sizePolicy)
        self.gridContainer.setFocusPolicy(QtCore.Qt.NoFocus)
        self.gridContainer.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
        self.gridContainer.setObjectName("Graphgrid")
        self.gridContainer.layout = QtWidgets.QGridLayout()
        self.dir = dir

        self.stockInfo = stockInfo

        self.dataX = dataX
        self.dataY = dataY
        self.rasingRange = []
        self.failingRange = []

        # setup Plot
        self.graph = None
        self.PlotDataItemList = None
        self.PlotLocalMaximaData = None
        self.PlotLocalMinimaData = None
        self.p1 = None
        self.colorStyle = ['r', 'g', 'y', 'b', 'w', 'o']
        self.setupGraph()
        self.gridContainer.layout.addWidget(self.graph, 0, 0, 10, 10)

        self.TableDAT = Concat_Table_With_IDX(self.dir, self.stockInfo.code)
        print(self.dir, self.stockInfo.code)
        self.initUI()
        self.proxy = pg.SignalProxy(self.p1.scene().sigMouseMoved,
                                    rateLimit=60,
                                    slot=self.mouseMoved)

    def initUI(self):
        #check box
        self.AVGRadioButton = QtWidgets.QCheckBox("AVG")
        self.AVGRadioButton.setObjectName("avgRadioButton")
        self.gridContainer.layout.addWidget(self.AVGRadioButton, 0, 11, 1, 1)
        self.AVGRadioButton.setStyleSheet("color: rgb(0, 255, 0);")
        self.AVGRadioButton.toggled.connect(
            lambda: self.toggleFunc(self.AVGRadioButton, 'avg'))
        self.AVGRadioButton.click()

        self.LPFRadioButton = QtWidgets.QCheckBox("LPF")
        self.LPFRadioButton.setObjectName("avgRadioButton")
        self.gridContainer.layout.addWidget(self.LPFRadioButton, 1, 11, 1, 1)
        self.LPFRadioButton.setStyleSheet("color: rgb(255,0,0);")
        self.LPFRadioButton.toggled.connect(
            lambda: self.toggleFunc(self.LPFRadioButton, 'lpf'))
        self.LPFRadioButton.click()

        #set Data
        self.PlotDataItemList = self.setPlot()
        self.setData(self.dataX, self.dataY)

        #set avg slide
        self.avgSld = QtWidgets.QSlider(QtCore.Qt.Horizontal, self)
        self.avgSld.setRange(5, 120)
        self.avgSld.setFocusPolicy(QtCore.Qt.NoFocus)
        # it seems not work
        #self.avgSld.setPageStep(5)
        # self.avgSld.setTickInterval(5)
        # self.avgSld.setSingleStep(5)
        self.avgSld.valueChanged.connect(self.updateAvg)
        self.gridContainer.layout.addWidget(self.avgSld, 11, 1, 1, 2)
        self.avg = functionAnalysis.moving_average(self.dataY['close'],
                                                   self.avgSld.value())

        self.AvgEdit = QtWidgets.QLabel('5日線')
        self.AvgEdit.setObjectName("avg")
        self.gridContainer.layout.addWidget(self.AvgEdit, 11, 0, 1, 1)

        self.OrderLabel = QtWidgets.QLabel('Order')
        self.OrderLabel.setObjectName("orderLabel")
        self.gridContainer.layout.addWidget(self.OrderLabel, 12, 0, 1, 1)

        self.OrderEdit = QtWidgets.QLineEdit("2")
        self.OrderEdit.setObjectName("orderEdit")
        self.gridContainer.layout.addWidget(self.OrderEdit, 12, 1, 1, 1)

        self.CutoffEdit = QtWidgets.QLabel("Cutoff : 2")
        self.CutoffEdit.setObjectName("Cutoff")
        self.gridContainer.layout.addWidget(self.CutoffEdit, 12, 3, 1, 1)

        self.cutoffSld = QtWidgets.QSlider(QtCore.Qt.Horizontal, self)
        self.cutoffSld.setRange(2, 60)

        self.cutoffSld.setFocusPolicy(QtCore.Qt.NoFocus)
        self.smoothData = functionAnalysis.butterworth_filter(
            self.dataY['close'], self.cutoffSld.value(),
            len(self.dataY['close']) / 2, 2)
        self.cutoffSld.valueChanged.connect(self.updateLPF)
        self.cutoffSld.setValue(5)

        self.gridContainer.layout.addWidget(self.cutoffSld, 12, 4, 1, 10)

        self.PlotDataItemList[1].setData(y=self.avg)
        self.PlotDataItemList[2].setData(y=self.smoothData)

        self.gridContainer.setLayout(self.gridContainer.layout)

        #make AVG is invisiable by default
        self.AVGRadioButton.setChecked(False)

        self.tableView = QtWidgets.QTableView()

        self.TableDAT = self.TableDAT.round(2)
        #Temporary, we delete 1st level colums, for showing columns in TableView
        self.TableDAT.columns = self.TableDAT.columns.droplevel(0)
        self.model = PandaModel.DataFrameModel(self.TableDAT)
        self.tableView.setModel(self.model)

        #Resize cell size to
        self.tableView.resizeColumnsToContents()
        self.gridContainer.layout.addWidget(self.tableView, 13, 0, 1, 10)

    def setupGraph(self):
        self.date_axis = TimeAxisItem(orientation='bottom')
        self.graph = GraphicsLayoutWidget()
        self.graph.setObjectName("Graph UI")
        self.date_axis = TimeAxisItem(orientation='bottom')
        self.label = pg.LabelItem(justify='right')
        self.graph.addItem(self.label)

        self.p1 = self.graph.addPlot(row=1,
                                     col=0,
                                     axisItems={'bottom': self.date_axis})
        #p1 zoom in/out, move viewbox can auto scaling Y, Important!
        self.p1.vb.sigXRangeChanged.connect(self.setYRange)

        self.PlotDataItemList = self.setPlot()
        self.PlotLocalMaximaData = pg.ScatterPlotItem(pen='r',
                                                      brush='b',
                                                      symbol='d',
                                                      pxMode=True,
                                                      size=10)
        self.PlotLocalMinimaData = pg.ScatterPlotItem(pen='g',
                                                      brush='b',
                                                      symbol='t',
                                                      pxMode=True,
                                                      size=10)
        # self.p1.addItem(self.PlotLocalMaximaData)
        # self.p1.addItem(self.PlotLocalMinimaData)

    # def showEvent(self, event):
    # 	geom = self.frameGeometry()
    # 	geom.moveCenter(QtGui.QCursor.pos())
    # 	self.setGeometry(geom)
    # 	super(Dialog, self).showEvent(event)

    def setPlot(self):
        PlotDataItemList = []
        self.name = ['close', 'avg', 'lpf']
        for i in range(0, 3):
            PlotDataItemList.append(
                self.p1.plot(pen=self.colorStyle[i], name=self.name[i]))
        return PlotDataItemList

    def setYRange(self, plotitem):
        plotitem.enableAutoRange(axis='y')
        plotitem.setAutoVisible(y=True)

    def setData(self, dataX, dataY):
        ticks = dict(enumerate(dataX))
        '''set X-value'''
        self.date_axis.setTicks(
            [list(ticks.items())[::120],
             list(ticks.items())[::1]])
        self.PlotDataItemList[0].setData(y=dataY['close'])

    def updateAvg(self, value):
        self.AvgEdit.setText(str(value) + '日線')
        self.avg = functionAnalysis.moving_average(self.dataY['close'],
                                                   self.avgSld.value())
        self.PlotDataItemList[1].setData(y=self.avg)

    def updateLPF(self, value):
        self.CutoffEdit.setText("Cutoff : " + str(value))
        self.smoothData = functionAnalysis.butterworth_filter(
            self.dataY['close'], self.cutoffSld.value(),
            len(self.dataY['close']) / 2, int(self.OrderEdit.text()))
        self.PlotDataItemList[2].setData(y=self.smoothData)
        maxidx, minidx = functionAnalysis.getlocalMaxMin(
            self.smoothData, True, True)

        #Split Range
        sortRange = []
        lastRoundIdx = 0
        for idxMax, idxMin in zip(maxidx, minidx):
            if idxMax > idxMin:
                sortRange.append([lastRoundIdx, idxMin])
                sortRange.append([idxMin, idxMax])
                lastRoundIdx = idxMax
            else:
                sortRange.append([lastRoundIdx, idxMax])
                sortRange.append([idxMax, idxMin])
                lastRoundIdx = idxMin
        sortRange.append([
            maxidx[-1], -1
        ]) if maxidx[-1] > minidx[-1] else sortRange.append([minidx[-1], -1])

        self.PlotLocalMaximaData.setData(
            x=maxidx, y=[self.dataY['close'][i] for i in maxidx])
        self.PlotLocalMinimaData.setData(
            x=minidx, y=[self.dataY['close'][i] for i in minidx])

    def keyPressEvent(self, event):
        if event.key() == QtCore.Qt.Key_Escape:
            self.hide()
            event.accept()
        else:
            super(Dialog, self).keyPressEvent(event)

    def toggleFunc(self, rdb, name):
        plotItem = None
        for plot in self.PlotDataItemList:
            if plot.name() == name:
                plotItem = plot
        if rdb.isChecked():
            self.p1.addItem(plotItem)
        else:
            self.p1.removeItem(plotItem)

    def mouseMoved(self, evt):
        pos = evt[
            0]  ## using signal proxy turns original arguments into a tuple

        if self.p1.sceneBoundingRect().contains(pos):
            mousePoint = self.p1.vb.mapSceneToView(pos)
            index = int(mousePoint.x())

            if index > 0 and index < len(self.dataX):
                idx = int(mousePoint.x())
                self.label.setText(
                    "<span style='font-size: 12pt'>x=%s,   <span style='color: red'>收盤價=%0.1f</span>"
                    % (self.dataX[idx], self.dataY['close'][idx]))
Example #20
0
class centralWidget(QtWidgets.QWidget):
    def __init__(self, timeData, voltsData):
        super(centralWidget, self).__init__()
        # first generating the widgets of the tab
        self.generateUiWidgets()
        # initializing important variables for plotting
        self.timeData = timeData
        self.originalVoltsData = voltsData
        self.editedVoltsData = voltsData
        self.plot = None  # original Plot
        self.plot1 = None  # plot After Editing

        self.xRangeStack = []
        self.yRangeStack = []

        self.sampleTime = timeData[1] - timeData[0]
        yrange = voltsData[len(voltsData) - 1] - voltsData[0]
        self.scrollStep_x = 100 * self.sampleTime
        self.scrollStep_y = yrange / 10

        # sliders values
        for i in range(1, 11):
            setattr(self, "_value" + str(i), 1)  # self._value[1-10] = 1

        #Pallete of spectrogram *viridis as deafult
        self.RGB_Pallete_1 = (0, 182, 188, 255)
        self.RGB_Pallete_2 = (246, 111, 0, 255)
        self.RGB_Pallete_3 = (75, 0, 113, 255)

        #set labels text
        ft = fourierTransform(self.originalVoltsData, int(1 / self.sampleTime))
        ranges = ft.rangesOfFrequancy

        for i in range(10):
            getattr(getattr(self, "label" + str(i + 1)),
                    "setText")(str(ranges[i][0] / 1000) + " Khz : \n" +
                               str(ranges[i][1] / 1000) + " Khz")

        self.HorizontalLabel1.setText("Set Minimun Frequancy")
        self.HorizontalLabel2.setText("Set Maximum Frequancy")

        # values of range of spectrogram
        self.minFreqOfSpectrogram = 0
        self.maxFreqOfSpectrogram = ranges[-1][1]

        self.horizontalSlider1.setMinimum(self.minFreqOfSpectrogram)
        self.horizontalSlider1.setMaximum(self.maxFreqOfSpectrogram)
        self.horizontalSlider1.setTickInterval(self.maxFreqOfSpectrogram / 10)

        self.horizontalSlider2.setMinimum(self.minFreqOfSpectrogram)
        self.horizontalSlider2.setMaximum(self.maxFreqOfSpectrogram)
        self.horizontalSlider2.setSliderPosition(self.maxFreqOfSpectrogram)
        self.horizontalSlider2.setTickInterval(self.maxFreqOfSpectrogram / 10)

        self.SpectrogramViewer.clear()
        self.drawSpectrogram()

        self.xRangeOfSignal = None  # [from , to]
        self.yRangeOfSignal = None

        #start plotting the data
        self.startPlotting()
        # get range of view of the plots
        self.xRangeOfSignal = [0.0, list(self.timeData)[-1]]  # [from , to]
        self.yRangeOfSignal = self.plot.viewRange()[1]

    def startPlotting(self):
        # plot original signal
        self.plot = self.OriginalSignalViewer.addPlot()
        self.plot.plot(self.timeData, self.originalVoltsData)
        # plot data After Editing
        self.plot1 = self.EditedSignalViewer.addPlot()
        self.plot1.plot(self.timeData, self.editedVoltsData)
        # range edit
        self.plot.setXRange(0.0, list(self.timeData)[-1], 0)
        self.plot1.setXRange(0.0, list(self.timeData)[-1], 0)

    def minSliderOfSpectrogram(self, value):
        self.minFreqOfSpectrogram = value
        self.SpectrogramViewer.clear()
        self.drawSpectrogram()

    def maxSliderOfSpectrogram(self, value):
        self.maxFreqOfSpectrogram = value
        self.SpectrogramViewer.clear()
        self.drawSpectrogram()

    def drawSpectrogram(self, minFreq=1, maxFreq=1):
        minFreq_Slider = self.minFreqOfSpectrogram
        maxFreq_Slider = self.maxFreqOfSpectrogram
        freq = 1 / self.sampleTime
        ft = fourierTransform(self.editedVoltsData, int(freq))
        ft.deleteRangeOfFrequancy(0, minFreq_Slider)
        ft.deleteRangeOfFrequancy(maxFreq_Slider, int(freq / 2))
        realsAfterEdit = ft.fn_InverceFourier(ft.data_fft)
        frequancyArr, timeArr, Sxx = signal.spectrogram(
            np.array(realsAfterEdit), freq)
        pyqtgraph.setConfigOptions(imageAxisOrder='row-major')

        win = self.SpectrogramViewer
        p1 = win.addPlot()

        img = pyqtgraph.ImageItem()
        p1.addItem(img)
        hist = pyqtgraph.HistogramLUTItem()
        hist.setImageItem(img)
        win.addItem(hist)
        hist.setLevels(np.min(Sxx), np.max(Sxx))
        hist.gradient.restoreState({
            'mode':
            'rgb',
            'ticks': [(0.5, self.RGB_Pallete_1), (1.0, self.RGB_Pallete_2),
                      (0.0, self.RGB_Pallete_3)]
        })
        img.setImage(Sxx)
        img.scale(timeArr[-1] / np.size(Sxx, axis=1),
                  frequancyArr[-1] / np.size(Sxx, axis=0))
        p1.setLimits(xMin=0, xMax=timeArr[-1], yMin=0, yMax=frequancyArr[-1])
        p1.setLabel('bottom', "Time", units='s')
        p1.setLabel('left', "Frequency", units='Hz')

    def generateUiWidgets(self):
        font = QtGui.QFont()
        font.setFamily("Arial Unicode MS")
        font.setPointSize(10)
        font.setBold(False)
        font.setItalic(False)
        font.setUnderline(False)
        font.setWeight(50)
        font.setStrikeOut(False)
        font.setKerning(True)
        self.setFont(font)
        self.setTabletTracking(False)
        self.gridLayout_6 = QtWidgets.QGridLayout(self)
        self.gridLayout_6.setObjectName("gridLayout_6")
        self.gridLayout_4 = QtWidgets.QGridLayout()
        self.gridLayout_4.setObjectName("gridLayout_4")
        self.SpectrogramGroupBox = QtWidgets.QGroupBox(self)
        font = QtGui.QFont()
        font.setFamily("Arial Unicode MS")
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.SpectrogramGroupBox.setFont(font)
        self.SpectrogramGroupBox.setStyleSheet(
            "border-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 0, 0, 255), stop:1 rgba(255, 255, 255, 255));"
        )
        self.SpectrogramGroupBox.setObjectName("SpectrogramGroupBox")
        self.gridLayout_2 = QtWidgets.QGridLayout(self.SpectrogramGroupBox)
        self.gridLayout_2.setObjectName("gridLayout_2")

        self.horizontalSlider2 = QtWidgets.QSlider(self.SpectrogramGroupBox)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.horizontalSlider2.setFont(font)
        self.horizontalSlider2.setCursor(
            QtGui.QCursor(QtCore.Qt.ClosedHandCursor))
        self.horizontalSlider2.setOrientation(QtCore.Qt.Horizontal)
        self.horizontalSlider2.setTickPosition(QtWidgets.QSlider.TicksBelow)
        self.horizontalSlider2.setTickInterval(1)
        self.horizontalSlider2.setObjectName("horizontalSlider2")
        self.gridLayout_2.addWidget(self.horizontalSlider2, 3, 0, 1, 1)

        self.SpectrogramViewer = GraphicsLayoutWidget(self.SpectrogramGroupBox)
        self.SpectrogramViewer.viewport().setProperty(
            "cursor", QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.SpectrogramViewer.setStyleSheet("background-color:rgb(0,0,0)")
        self.SpectrogramViewer.setObjectName("SpectrogramViewer")
        self.gridLayout_2.addWidget(self.SpectrogramViewer, 0, 0, 1, 1)

        self.horizontalSlider1 = QtWidgets.QSlider(self.SpectrogramGroupBox)
        self.horizontalSlider1.setCursor(
            QtGui.QCursor(QtCore.Qt.ClosedHandCursor))
        self.horizontalSlider1.setOrientation(QtCore.Qt.Horizontal)
        self.horizontalSlider1.setTickPosition(QtWidgets.QSlider.TicksBelow)
        self.horizontalSlider1.setTickInterval(1)
        self.horizontalSlider1.setObjectName("horizontalSlider1")
        self.gridLayout_2.addWidget(self.horizontalSlider1, 1, 0, 1, 1)
        self.HorizontalLabel1 = QtWidgets.QLabel(self.SpectrogramGroupBox)
        font = QtGui.QFont()
        font.setPointSize(7)
        self.HorizontalLabel1.setFont(font)
        self.HorizontalLabel1.setAlignment(QtCore.Qt.AlignCenter)
        self.HorizontalLabel1.setObjectName("HorizontalLabel1")
        self.gridLayout_2.addWidget(self.HorizontalLabel1, 2, 0, 1, 1)
        self.HorizontalLabel2 = QtWidgets.QLabel(self.SpectrogramGroupBox)
        self.HorizontalLabel2.setAlignment(QtCore.Qt.AlignCenter)
        self.HorizontalLabel2.setObjectName("HorizontalLabel2")
        self.gridLayout_2.addWidget(self.HorizontalLabel2, 4, 0, 1, 1)

        self.gridLayout_4.addWidget(self.SpectrogramGroupBox, 0, 1, 3, 1)
        self.OriginalSignalGroupbox = QtWidgets.QGroupBox(self)
        font = QtGui.QFont()
        font.setFamily("Arial Unicode MS")
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.OriginalSignalGroupbox.setFont(font)
        self.OriginalSignalGroupbox.setObjectName("OriginalSignalGroupbox")
        self.gridLayout_5 = QtWidgets.QGridLayout(self.OriginalSignalGroupbox)
        self.gridLayout_5.setObjectName("gridLayout_5")
        self.OriginalSignalViewer = GraphicsLayoutWidget(
            self.OriginalSignalGroupbox)
        self.OriginalSignalViewer.viewport().setProperty(
            "cursor", QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.OriginalSignalViewer.setStyleSheet(
            "background-color: rgb(0, 0, 0);")
        self.OriginalSignalViewer.setObjectName("OriginalSignalViewer")
        self.gridLayout_5.addWidget(self.OriginalSignalViewer, 0, 0, 1, 1)
        self.gridLayout_4.addWidget(self.OriginalSignalGroupbox, 0, 0, 1, 1)
        self.EditedSignalGroupBox = QtWidgets.QGroupBox(self)
        font = QtGui.QFont()
        font.setFamily("Arial Unicode MS")
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.EditedSignalGroupBox.setFont(font)
        self.EditedSignalGroupBox.setObjectName("EditedSignalGroupBox")
        self.gridLayout_3 = QtWidgets.QGridLayout(self.EditedSignalGroupBox)
        self.gridLayout_3.setObjectName("gridLayout_3")
        self.EditedSignalViewer = GraphicsLayoutWidget(
            self.EditedSignalGroupBox)
        self.EditedSignalViewer.viewport().setProperty(
            "cursor", QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        self.EditedSignalViewer.setStyleSheet("background-color:rgb(0,0,0)")
        self.EditedSignalViewer.setObjectName("EditedSignalViewer")
        self.gridLayout_3.addWidget(self.EditedSignalViewer, 0, 0, 1, 1)
        self.gridLayout_4.addWidget(self.EditedSignalGroupBox, 2, 0, 1, 1)
        self.SignalEditorGroupBox = QtWidgets.QGroupBox(self)
        font = QtGui.QFont()
        font.setFamily("Arial Unicode MS")
        font.setPointSize(10)
        font.setBold(True)
        font.setWeight(75)
        self.SignalEditorGroupBox.setFont(font)
        self.SignalEditorGroupBox.setObjectName("SignalEditorGroupBox")
        self.gridLayout = QtWidgets.QGridLayout(self.SignalEditorGroupBox)
        self.gridLayout.setObjectName("gridLayout")
        self.gridLayout_7 = QtWidgets.QGridLayout()
        self.gridLayout_7.setObjectName("gridLayout_7")

        # add 10 labels for 10 sliders
        for i in range(10):
            setattr(
                self, "label" + str(i + 1),
                QtWidgets.QLabel(self.SignalEditorGroupBox)
            )  # self.label[1-10] = QtWidgets.QLabel(self.SignalEditorGroupBox)
            font = QtGui.QFont()
            font.setPointSize(5)
            font.setBold(False)
            font.setWeight(50)
            getattr(getattr(self, "label" + str(i + 1)),
                    "setFont")(font)  #self.label1.setFont(font)
            getattr(getattr(self, "label" + str(i + 1)), "setObjectName")(
                "label" +
                str(i + 1))  #self.label[1-10].setObjectName("label[1-10]")
            getattr(getattr(self, "gridLayout_7"), "addWidget")(
                getattr(self, "label" + str(i + 1)), 0, i, 1,
                1)  #self.gridLayout_7.addWidget(self.label1, 0, 0, 1, 1)

        self.gridLayout.addLayout(self.gridLayout_7, 1, 0, 1, 10)

        # add 10 sliders to gui
        for i in range(10):
            setattr(
                self, "slider" + str(i + 1),
                Slider(parent=self.SignalEditorGroupBox,
                       objectName="Slider" + str(i + 1)))
            Slid = getattr(self, "slider" + str(i + 1))
            getattr(getattr(self, "gridLayout"), "addWidget")(Slid, 0, i, 1, 1)
            # link slider to the trigger function
            Slid.valueChanged.connect(lambda v: self.fn_sliderValue(v))

        self.gridLayout_4.addWidget(self.SignalEditorGroupBox, 1, 0, 1, 1)
        self.gridLayout_6.addLayout(self.gridLayout_4, 0, 0, 1, 1)

        self.horizontalSlider1.valueChanged[int].connect(
            self.minSliderOfSpectrogram)
        self.horizontalSlider2.valueChanged[int].connect(
            self.maxSliderOfSpectrogram)
        QtCore.QMetaObject.connectSlotsByName(self)

    def fn_sliderValue(self, value):
        objectName = str(self.sender().objectName())
        sliderNumber = re.search("[0-9]+", objectName).group()
        setattr(self, "_value" + sliderNumber, value)
        self.process()

    def process(self):  #(freq,complex_data,reals,time,np.abs(complex_data))
        ft = fourierTransform(
            list(self.originalVoltsData).copy(), 1 / self.sampleTime)
        complex_data = ft.gain(self._value1, self._value2, self._value3,
                               self._value4, self._value5, self._value6,
                               self._value7, self._value8, self._value9,
                               self._value10)
        reals = ft.fn_InverceFourier(complex_data)
        #update Plot
        self.EditedSignalViewer.clear()
        self.plot1 = self.EditedSignalViewer.addPlot()
        self.plot1.plot(self.timeData, reals)
        self.plot1.setXRange(self.xRangeOfSignal[0], self.xRangeOfSignal[1], 0)
        self.plot1.setYRange(self.yRangeOfSignal[0], self.yRangeOfSignal[1], 0)
        self.editedVoltsData = np.array(reals)
        # update spectrogram
        self.SpectrogramViewer.clear()
        self.drawSpectrogram()

    def playSound(self):
        ft = fourierTransform(
            list(self.editedVoltsData).copy(), 1 / self.sampleTime)
        complex_data = ft.gain(self._value1, self._value2, self._value3,
                               self._value4, self._value5, self._value6,
                               self._value7, self._value8, self._value9,
                               self._value10)
        reals = ft.fn_InverceFourier(complex_data)
        sound = soundfileUtility()
        sound.fn_CreateSoundFile(list(reals), int(1 / self.sampleTime))
        sound.fn_PlaySoundFile()
class astraPlotWidget(QWidget):

    twissplotLayout = [
        {
            'name': 'sigma_x',
            'range': [0, 1],
            'scale': 1e3
        },
        {
            'name': 'sigma_y',
            'range': [0, 1],
            'scale': 1e3
        },
        {
            'name': 'kinetic_energy',
            'range': [0, 250],
            'scale': 1e-6
        },
        'next_row',
        {
            'name': 'sigma_p',
            'range': [0, 0.015],
            'scale': 1e6
        },
        {
            'name': 'sigma_z',
            'range': [0, 0.6],
            'scale': 1e3
        },
        {
            'name': 'enx',
            'range': [0.5, 1.5],
            'scale': 1e6
        },
        'next_row',
        {
            'name': 'eny',
            'range': [0.5, 1.5],
            'scale': 1e6
        },
        {
            'name': 'beta_x',
            'range': [0, 150],
            'scale': 1
        },
        {
            'name': 'beta_y',
            'range': [0, 150],
            'scale': 1
        },
    ]

    def __init__(self, directory='.', **kwargs):
        super(astraPlotWidget, self).__init__(**kwargs)
        self.beam = raf.beam()
        self.twiss = rtf.twiss()
        self.directory = directory
        ''' twissPlotWidget '''
        self.twissPlotView = GraphicsView(useOpenGL=True)
        self.twissPlotWidget = GraphicsLayout()
        self.twissPlotView.setCentralItem(self.twissPlotWidget)

        self.latticePlotData = imageio.imread('lattice_plot.png')
        self.latticePlots = {}
        self.twissPlots = {}
        i = -1
        for entry in self.twissplotLayout:
            if entry == 'next_row':
                self.twissPlotWidget.nextRow()
            else:
                i += 1
                p = self.twissPlotWidget.addPlot(title=entry['name'])
                p.showGrid(x=True, y=True)
                vb = p.vb
                vb.setYRange(*entry['range'])
                latticePlot = ImageItem(self.latticePlotData)
                latticePlot.setOpts(axisOrder='row-major')
                vb.addItem(latticePlot)
                latticePlot.setZValue(-1)  # make sure this image is on top
                # latticePlot.setOpacity(0.5)
                self.twissPlots[entry['name']] = p.plot(
                    pen=mkPen('b', width=3))
                self.latticePlots[p.vb] = latticePlot
                p.vb.sigRangeChanged.connect(self.scaleLattice)
        ''' beamPlotWidget '''
        self.beamPlotWidget = QWidget()
        self.beamPlotLayout = QVBoxLayout()
        self.item = ImageItem()
        self.beamPlotWidget.setLayout(self.beamPlotLayout)
        self.beamPlotView = ImageView(imageItem=self.item)
        self.rainbow = rainbow()
        self.item.setLookupTable(self.rainbow)
        self.item.setLevels([0, 1])
        # self.beamPlotWidgetGraphicsLayout = GraphicsLayout()
        # p = self.beamPlotWidgetGraphicsLayout.addPlot(title='beam')
        # p.showGrid(x=True, y=True)
        # self.beamPlot = p.plot(pen=None, symbol='+')
        # self.beamPlotView.setCentralItem(self.beamPlotWidgetGraphicsLayout)
        self.beamPlotXAxisCombo = QComboBox()
        self.beamPlotXAxisCombo.addItems(
            ['x', 'y', 'zn', 'cpx', 'cpy', 'BetaGamma'])
        self.beamPlotYAxisCombo = QComboBox()
        self.beamPlotYAxisCombo.addItems(
            ['x', 'y', 'zn', 'cpx', 'cpy', 'BetaGamma'])
        self.beamPlotNumberBins = QSpinBox()
        self.beamPlotNumberBins.setRange(10, 500)
        self.beamPlotNumberBins.setSingleStep(10)
        self.histogramBins = 100
        self.beamPlotNumberBins.setValue(self.histogramBins)
        self.beamPlotAxisWidget = QWidget()
        self.beamPlotAxisLayout = QHBoxLayout()
        self.beamPlotAxisWidget.setLayout(self.beamPlotAxisLayout)
        self.beamPlotAxisLayout.addWidget(self.beamPlotXAxisCombo)
        self.beamPlotAxisLayout.addWidget(self.beamPlotYAxisCombo)
        self.beamPlotAxisLayout.addWidget(self.beamPlotNumberBins)
        self.beamPlotXAxisCombo.currentIndexChanged.connect(self.plotDataBeam)
        self.beamPlotYAxisCombo.currentIndexChanged.connect(self.plotDataBeam)
        self.beamPlotNumberBins.valueChanged.connect(self.plotDataBeam)
        # self.beamPlotXAxisCombo.setCurrentIndex(2)
        # self.beamPlotYAxisCombo.setCurrentIndex(5)
        self.beamPlotLayout.addWidget(self.beamPlotAxisWidget)
        self.beamPlotLayout.addWidget(self.beamPlotView)
        ''' slicePlotWidget '''
        self.sliceParams = [
            {
                'name': 'slice_normalized_horizontal_emittance',
                'units': 'm-rad',
                'text': 'enx'
            },
            {
                'name': 'slice_normalized_vertical_emittance',
                'units': 'm-rad',
                'text': 'eny'
            },
            {
                'name': 'slice_peak_current',
                'units': 'A',
                'text': 'PeakI'
            },
            {
                'name': 'slice_relative_momentum_spread',
                'units': '%',
                'text': 'sigma-p'
            },
        ]
        self.slicePlotWidget = QWidget()
        self.slicePlotLayout = QVBoxLayout()
        self.slicePlotWidget.setLayout(self.slicePlotLayout)
        # self.slicePlotView = GraphicsView(useOpenGL=True)
        self.slicePlotWidgetGraphicsLayout = GraphicsLayoutWidget()
        # self.slicePlots = {}
        self.slicePlotCheckbox = {}
        self.curve = {}
        self.sliceaxis = {}
        self.slicePlotCheckboxWidget = QWidget()
        self.slicePlotCheckboxLayout = QVBoxLayout()
        self.slicePlotCheckboxWidget.setLayout(self.slicePlotCheckboxLayout)
        self.slicePlot = self.slicePlotWidgetGraphicsLayout.addPlot(
            title='Slice', row=0, col=50)
        self.slicePlot.showAxis('left', False)
        self.slicePlot.showGrid(x=True, y=True)
        i = -1
        colors = ['b', 'r', 'g', 'k']
        for param in self.sliceParams:
            i += 1
            axis = AxisItem("left")
            labelStyle = {'color': '#' + colorStr(mkColor(colors[i]))[0:-2]}
            axis.setLabel(text=param['text'],
                          units=param['units'],
                          **labelStyle)
            viewbox = ViewBox()
            axis.linkToView(viewbox)
            viewbox.setXLink(self.slicePlot.vb)
            self.sliceaxis[param['name']] = [axis, viewbox]
            self.curve[param['name']] = PlotDataItem(pen=colors[i], symbol='+')
            viewbox.addItem(self.curve[param['name']])
            col = self.findFirstEmptyColumnInGraphicsLayout()
            self.slicePlotWidgetGraphicsLayout.ci.addItem(axis,
                                                          row=0,
                                                          col=col,
                                                          rowspan=1,
                                                          colspan=1)
            self.slicePlotWidgetGraphicsLayout.ci.addItem(viewbox,
                                                          row=0,
                                                          col=50)
            p.showGrid(x=True, y=True)
            # self.slicePlots[param] = self.slicePlot.plot(pen=colors[i], symbol='+')
            self.slicePlotCheckbox[param['name']] = QCheckBox(param['text'])
            self.slicePlotCheckboxLayout.addWidget(
                self.slicePlotCheckbox[param['name']])
            self.slicePlotCheckbox[param['name']].stateChanged.connect(
                self.plotDataSlice)
        # self.slicePlotView.setCentralItem(self.slicePlotWidgetGraphicsLayout)
        self.slicePlotSliceWidthWidget = QSpinBox()
        self.slicePlotSliceWidthWidget.setMaximum(1000)
        self.slicePlotSliceWidthWidget.setValue(100)
        self.slicePlotSliceWidthWidget.setSingleStep(10)
        self.slicePlotSliceWidthWidget.setSuffix("fs")
        self.slicePlotSliceWidthWidget.setSpecialValueText('Automatic')
        self.slicePlotAxisWidget = QWidget()
        self.slicePlotAxisLayout = QHBoxLayout()
        self.slicePlotAxisWidget.setLayout(self.slicePlotAxisLayout)
        self.slicePlotAxisLayout.addWidget(self.slicePlotCheckboxWidget)
        self.slicePlotAxisLayout.addWidget(self.slicePlotSliceWidthWidget)
        # self.slicePlotXAxisCombo.currentIndexChanged.connect(self.plotDataSlice)
        self.slicePlotSliceWidthWidget.valueChanged.connect(
            self.changeSliceLength)
        # self.beamPlotXAxisCombo.setCurrentIndex(2)
        # self.beamPlotYAxisCombo.setCurrentIndex(5)
        self.slicePlotLayout.addWidget(self.slicePlotAxisWidget)
        self.slicePlotLayout.addWidget(self.slicePlotWidgetGraphicsLayout)

        self.layout = QVBoxLayout()
        self.setLayout(self.layout)

        self.tabWidget = QTabWidget()

        self.folderButton = QPushButton('Select Directory')
        self.folderLineEdit = QLineEdit()
        self.folderLineEdit.setReadOnly(True)
        self.folderLineEdit.setText(self.directory)
        self.reloadButton = QPushButton()
        self.reloadButton.setIcon(qApp.style().standardIcon(
            QStyle.SP_BrowserReload))
        self.folderWidget = QGroupBox()
        self.folderLayout = QHBoxLayout()
        self.folderLayout.addWidget(self.folderButton)
        self.folderLayout.addWidget(self.folderLineEdit)
        self.folderLayout.addWidget(self.reloadButton)
        self.folderWidget.setLayout(self.folderLayout)
        self.folderWidget.setMaximumWidth(800)
        self.reloadButton.clicked.connect(
            lambda: self.changeDirectory(self.directory))
        self.folderButton.clicked.connect(self.changeDirectory)

        self.fileSelector = QComboBox()
        self.fileSelector.currentIndexChanged.connect(self.updateScreenCombo)
        self.screenSelector = QComboBox()
        self.screenSelector.currentIndexChanged.connect(self.changeScreen)
        self.beamWidget = QGroupBox()
        self.beamLayout = QHBoxLayout()
        self.beamLayout.addWidget(self.fileSelector)
        self.beamLayout.addWidget(self.screenSelector)
        self.beamWidget.setLayout(self.beamLayout)
        self.beamWidget.setMaximumWidth(800)
        self.beamWidget.setVisible(False)

        self.folderBeamWidget = QWidget()
        self.folderBeamLayout = QHBoxLayout()
        self.folderBeamLayout.setAlignment(Qt.AlignLeft)
        self.folderBeamWidget.setLayout(self.folderBeamLayout)
        self.folderBeamLayout.addWidget(self.folderWidget)
        self.folderBeamLayout.addWidget(self.beamWidget)

        self.tabWidget.addTab(self.twissPlotView, 'Twiss Plots')
        self.tabWidget.addTab(self.beamPlotWidget, 'Beam Plots')
        self.tabWidget.addTab(self.slicePlotWidget, 'Slice Beam Plots')
        self.tabWidget.currentChanged.connect(self.changeTab)
        self.layout.addWidget(self.folderBeamWidget)
        self.layout.addWidget(self.tabWidget)

        self.plotType = 'Twiss'
        self.changeDirectory(self.directory)

    def findFirstEmptyColumnInGraphicsLayout(self):
        rowsfilled = self.slicePlotWidgetGraphicsLayout.ci.rows.get(0,
                                                                    {}).keys()
        for i in range(49):
            if not i in rowsfilled:
                return i

    def changeTab(self, i):
        if self.tabWidget.tabText(i) == 'Beam Plots':
            self.plotType = 'Beam'
            self.beamWidget.setVisible(True)
        elif self.tabWidget.tabText(i) == 'Slice Beam Plots':
            self.plotType = 'Slice'
            self.beamWidget.setVisible(True)
        else:
            self.plotType = 'Twiss'
            self.beamWidget.setVisible(False)
        self.loadDataFile()

    def changeDirectory(self, directory=None):
        if directory == None or directory == False:
            self.directory = str(
                QFileDialog.getExistingDirectory(self, "Select Directory",
                                                 self.directory,
                                                 QFileDialog.ShowDirsOnly))
        else:
            self.directory = directory
        self.folderLineEdit.setText(self.directory)
        self.currentFileText = self.fileSelector.currentText()
        self.currentScreenText = self.screenSelector.currentText()
        self.getScreenFiles()
        self.updateFileCombo()
        self.updateScreenCombo()
        self.loadDataFile()

    def getScreenFiles(self):
        self.screenpositions = {}
        files = glob.glob(self.directory + '/*.????.???')
        filenames = [
            '.'.join(os.path.basename(f).split('.')[:-2]) for f in files
        ]
        print 'filenames = ', filenames
        runnumber = [os.path.basename(f).split('.')[-1] for f in files]
        for f, r in list(set(zip(filenames, runnumber))):
            files = glob.glob(self.directory + '/' + f + '.????.???')
            screenpositions = [
                re.search(f + '\.(\d\d\d\d)\.\d\d\d', s).group(1)
                for s in files
            ]
            print 'screenpositions = ', screenpositions
            self.screenpositions[f] = {
                'screenpositions': sorted(screenpositions),
                'run': r
            }

    def updateFileCombo(self):
        self.fileSelector.clear()
        i = -1
        screenfirstpos = []
        for f in self.screenpositions:
            screenfirstpos.append(
                [f, min(self.screenpositions[f]['screenpositions'])])
        screenfirstpos = np.array(screenfirstpos)
        sortedscreennames = screenfirstpos[np.argsort(
            np.array(screenfirstpos)[:, 1])]
        print 'sortedscreennames = ', sortedscreennames
        for f in sortedscreennames:
            self.fileSelector.addItem(f[0])
            i += 1
            if f[0] == self.currentFileText:
                self.fileSelector.setCurrentIndex(i)

    def changeScreen(self, i):
        run = self.screenpositions[str(self.fileSelector.currentText())]['run']
        self.beamFileName = str(self.fileSelector.currentText()) + '.' + str(
            self.screenSelector.currentText()) + '.' + str(run)
        # print 'beamFileName = ', self.beamFileName
        self.loadDataFile()

    def updateScreenCombo(self):
        self.screenSelector.clear()
        i = -1
        for s in self.screenpositions[str(
                self.fileSelector.currentText())]['screenpositions']:
            self.screenSelector.addItem(s)
            i += 1
            if s == self.currentScreenText:
                self.screenSelector.setCurrentIndex(i)

    def loadDataFile(self):
        if self.plotType == 'Twiss':
            files = sorted(glob.glob(self.directory + "/*Xemit*"))
            self.twiss.read_astra_emit_files(files)
            self.plotDataTwiss()
        elif self.plotType == 'Beam' or self.plotType == 'Slice':
            if hasattr(
                    self,
                    'beamFileName') and os.path.isfile(self.directory + '/' +
                                                       self.beamFileName):
                # starttime = time.time()
                self.beam.read_astra_beam_file(self.directory + '/' +
                                               self.beamFileName)
                # print 'reading file took ', time.time()-starttime, 's'
                # print 'Read file: ', self.beamFileName
                if self.plotType == 'Beam':
                    self.plotDataBeam()
                else:
                    self.beam.bin_time()
                    self.plotDataSlice()

    def plotDataTwiss(self):
        for entry in self.twissplotLayout:
            if entry == 'next_row':
                pass
            else:
                x = self.twiss['z']
                y = self.twiss[entry['name']] * entry['scale']
                xy = np.transpose(np.array([x, y]))
                x, y = np.transpose(xy[np.argsort(xy[:, 0])])
                self.twissPlots[entry['name']].setData(x=x,
                                                       y=y,
                                                       pen=mkPen('b', width=3))

    def plotDataBeam(self):
        self.histogramBins = self.beamPlotNumberBins.value()
        x = getattr(self.beam, str(self.beamPlotXAxisCombo.currentText()))
        y = getattr(self.beam, str(self.beamPlotYAxisCombo.currentText()))
        h, xedges, yedges = np.histogram2d(x,
                                           y,
                                           self.histogramBins,
                                           normed=True)
        x0 = xedges[0]
        y0 = yedges[0]
        xscale = (xedges[-1] - xedges[0]) / len(xedges)
        yscale = (yedges[-1] - yedges[0]) / len(yedges)
        self.item.setImage(h)
        self.item.setLookupTable(self.rainbow)
        # self.item.setLevels([0,1])

    def changeSliceLength(self):
        self.beam.slice_length = self.slicePlotSliceWidthWidget.value() * 1e-15
        self.beam.bin_time()
        self.plotDataSlice()

    def plotDataSlice(self):
        for param in self.sliceParams:
            if self.slicePlotCheckbox[param['name']].isChecked():
                x = self.beam.slice_bins
                self.slicePlot.setRange(xRange=[min(x), max(x)])
                # self.plot.setRange(xRange=[-0.5,1.5])
                y = getattr(self.beam, param['name'])
                self.curve[param['name']].setData(x=x, y=y)
                self.sliceaxis[param['name']][0].setVisible(True)
                # currentrange = self.sliceaxis[param['name']][0].range
                # print 'currentrange = ', currentrange
                # self.sliceaxis[param['name']][0].setRange(0, currentrange[1])
            else:
                # pass
                self.curve[param['name']].setData(x=[], y=[])
                self.sliceaxis[param['name']][0].setVisible(False)
            self.sliceaxis[param['name']][1].autoRange()
            currentrange = self.sliceaxis[param['name']][1].viewRange()
            self.sliceaxis[param['name']][1].setYRange(0, currentrange[1][1])

    def scaleLattice(self, vb, range):
        yrange = range[1]
        scaleY = 0.05 * abs(yrange[1] - yrange[0])
        rect = QRectF(0, yrange[0] + 2 * scaleY, 49.2778, 4 * scaleY)
        self.latticePlots[vb].setRect(rect)
Example #22
0
class Graphexample():
    def __init__(self):
        self.graph = GraphicsLayoutWidget()
        self.graph.setObjectName("stock UI")
        self.label = pg.LabelItem(justify='right')
        self.graph.addItem(self.label)
        self.p1 = self.graph.addPlot(row=1, col=0)
        self.p2 = self.graph.addPlot(row=2, col=0)
        self.p1.showGrid(x=True, y=True, alpha=0.5)
        self.region = pg.LinearRegionItem()
        self.region.setZValue(10)
        # Add the LinearRegionItem to the ViewBox, but tell the ViewBox to exclude this
        # item when doing auto-range calculations.
        self.p2.addItem(self.region, ignoreBounds=True)

        #pg.dbg()
        self.p1.setAutoVisible(y=True)

        #create numpy arrays
        #make the numbers large to show that the xrange shows data from 10000 to all the way 0
        self.data1 = 10000 + 15000 * pg.gaussianFilter(
            np.random.random(size=10000),
            10) + 3000 * np.random.random(size=10000)
        self.data2 = 15000 + 15000 * pg.gaussianFilter(
            np.random.random(size=10000),
            10) + 3000 * np.random.random(size=10000)

        self.p1.plot(self.data1, pen="r")
        self.p1.plot(self.data2, pen="g")

        self.p2.plot(self.data1, pen="w")
        self.region.sigRegionChanged.connect(self.update)
        self.p1.sigRangeChanged.connect(self.updateRegion)

        self.region.setRegion([1000, 2000])

        #cross hair
        self.vLine = pg.InfiniteLine(angle=90, movable=False)
        self.hLine = pg.InfiniteLine(angle=0, movable=False)
        self.p1.addItem(self.vLine, ignoreBounds=True)
        self.p1.addItem(self.hLine, ignoreBounds=True)

        self.vb = self.p1.vb
        self.proxy = pg.SignalProxy(self.p1.scene().sigMouseMoved,
                                    rateLimit=60,
                                    slot=self.mouseMoved)

    def update(self):
        self.region.setZValue(10)
        minX, maxX = self.region.getRegion()
        self.p1.setXRange(minX, maxX, padding=0)

    def updateRegion(self, window, viewRange):
        rgn = viewRange[0]
        self.region.setRegion(rgn)

    def mouseMoved(self, evt):
        pos = evt[
            0]  ## using signal proxy turns original arguments into a tuple
        if self.p1.sceneBoundingRect().contains(pos):
            mousePoint = self.vb.mapSceneToView(pos)
            index = int(mousePoint.x())
            if index > 0 and index < len(self.data1):
                self.label.setText(
                    "<span style='font-size: 12pt'>x=%0.1f,   <span style='color: red'>y1=%0.1f</span>,   <span style='color: green'>y2=%0.1f</span>"
                    % (mousePoint.x(), self.data1[index], self.data2[index]))
            self.vLine.setPos(mousePoint.x())
            self.hLine.setPos(mousePoint.y())

    def ret_GraphicsLayoutWidget(self):
        return self.graph
Example #23
0
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1150, 699)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")

        self.graphicsView = GraphicsLayoutWidget(self.centralwidget)
        self.graphicsView.setGeometry(QtCore.QRect(180, 10, 931, 651))
        self.graphicsView.setObjectName("graphicsView")
        self.ts_plots = [
            self.graphicsView.addPlot(row=i,
                                      col=0,
                                      colspan=2,
                                      title='Channel %d' % i,
                                      labels={'left': 'uV'})
            for i in range(1, 9)
        ]

        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(10, 500, 131, 41))
        self.pushButton.setObjectName("pushButton")
        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(10, 390, 131, 41))
        self.pushButton_2.setObjectName("pushButton_2")
        self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_3.setGeometry(QtCore.QRect(10, 60, 141, 41))
        self.pushButton_3.setObjectName("pushButton_3")
        self.lcdNumber = QtWidgets.QLCDNumber(self.centralwidget)
        self.lcdNumber.setGeometry(QtCore.QRect(20, 250, 111, 61))
        self.lcdNumber.setSmallDecimalPoint(True)
        self.lcdNumber.setDigitCount(3)
        self.lcdNumber.setSegmentStyle(QtWidgets.QLCDNumber.Flat)
        self.lcdNumber.setObjectName("lcdNumber")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(100, 140, 61, 41))
        self.label.setObjectName("label")
        self.textEdit = QtWidgets.QTextEdit(self.centralwidget)
        self.textEdit.setGeometry(QtCore.QRect(20, 140, 71, 41))
        self.textEdit.setObjectName("textEdit")
        MainWindow.setCentralWidget(self.centralwidget)

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

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton.setText(_translate("MainWindow", "SALIR"))
        self.pushButton_2.setText(_translate("MainWindow", "INICIO"))
        self.pushButton_3.setText(_translate("MainWindow", "ACTUALIZAR"))
        self.label.setText(_translate("MainWindow", "SEGUNDOS."))

    ################################################################################
    def save_data(self, sample):
        global data
        data.append([i * SCALE_FACTOR for i in sample.channels_data])

    def updater(self):
        global data, plots, colors
        t_data = np.array(data[-1250:]).T  #transpose data
        fs = 250  #Hz
        # Plot a time series of the raw data
        for j in range(8):
            self.ts_plots[j].clear()
            # self.ts_plots[j].plot(t_data[j])
            self.ts_plots[j].plot(pen=colors[j]).setData(t_data[j])
Example #24
0
File: moldy.py Project: shrx/moldy
class MainWidget(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        # define periodic table widget for element selection
        self.periodicTableWidget = widgets.PeriodicTableDialog()

        # initial molecule Zmatrix (can be empty)
        # self.inp = []
        self.inp = [['H'],
        ['O', 1, 0.9],
        ['O', 2, 1.4, 1, 105.],
        ['H', 3, 0.9, 2, 105., 1, 120.]]

        self.atomList = []
        self.highList = []
        self.labelList = []
        self.fast = False

        # define & initialize ZMatModel that will contain Zmatrix data
        self.ZMatModel = QStandardItemModel(len(self.inp), 7, self)
        self.ZMatTable = QTableView(self)
        self.ZMatTable.setModel(self.ZMatModel)
        self.ZMatTable.setFixedWidth(325)
        #self.ZMatTable.installEventFilter(self)
        #self.ZMatModel.installEventFilter(self)
        self.ZMatModel.setHorizontalHeaderLabels(['atom','','bond','','angle','','dihedral'])
        for j, width in enumerate([40, 22, 65, 22, 65, 22, 65]):
            self.ZMatTable.setColumnWidth(j, width)
        # populate the ZMatModel
        self.populateZMatModel()

        #define Menu bar menus and their actions
        self.menuBar = QMenuBar(self)
        fileMenu = self.menuBar.addMenu('&File')
        editMenu = self.menuBar.addMenu('&Edit')
        viewMenu = self.menuBar.addMenu('&View')
        measureMenu = self.menuBar.addMenu('&Measure')
        helpMenu = self.menuBar.addMenu('&Help')

        readZmatAction = QAction('&Read &ZMat', self)
        readZmatAction.setShortcut('Ctrl+O')
        readZmatAction.setStatusTip('Read Zmat from file')
        readZmatAction.triggered.connect(self.readZmat)
        fileMenu.addAction(readZmatAction)

        readXYZAction = QAction('&Read &XYZ', self)
        readXYZAction.setShortcut('Ctrl+Shift+O')
        readXYZAction.setStatusTip('Read XYZ from file')
        readXYZAction.triggered.connect(self.readXYZ)
        fileMenu.addAction(readXYZAction)

        readGaussianAction = QAction('&Read &Gaussian log', self)
        readGaussianAction.setShortcut('Ctrl+G')
        readGaussianAction.setStatusTip('Read Gaussian log file')
        readGaussianAction.triggered.connect(self.readGaussian)
        fileMenu.addAction(readGaussianAction)

        writeZmatAction = QAction('&Write &ZMat', self)
        writeZmatAction.setShortcut('Ctrl+S')
        writeZmatAction.setStatusTip('Write Zmat to file')
        writeZmatAction.triggered.connect(self.writeZmat)
        fileMenu.addAction(writeZmatAction)

        writeXYZAction = QAction('&Write &XYZ', self)
        writeXYZAction.setShortcut('Ctrl+Shift+S')
        writeXYZAction.setStatusTip('Write XYZ from file')
        writeXYZAction.triggered.connect(self.writeXYZ)
        fileMenu.addAction(writeXYZAction)

        exitAction = QAction('&Exit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit application')
        exitAction.triggered.connect(qApp.quit)
        fileMenu.addAction(exitAction)

        addRowAction = QAction('&Add &row', self)
        addRowAction.setShortcut('Ctrl+R')
        addRowAction.setStatusTip('Add row to ZMatrix')
        addRowAction.triggered.connect(self.addRow)
        editMenu.addAction(addRowAction)

        deleteRowAction = QAction('&Delete &row', self)
        deleteRowAction.setShortcut('Ctrl+Shift+R')
        deleteRowAction.setStatusTip('Delete row from ZMatrix')
        deleteRowAction.triggered.connect(self.deleteRow)
        editMenu.addAction(deleteRowAction)

        addAtomAction = QAction('&Add &atom', self)
        addAtomAction.setShortcut('Ctrl+A')
        addAtomAction.setStatusTip('Add atom to ZMatrix')
        addAtomAction.triggered.connect(self.buildB)
        editMenu.addAction(addAtomAction)

        drawModeMenu = QMenu('Draw mode', self)
        viewMenu.addMenu(drawModeMenu)
        fastDrawAction = QAction('&Fast draw', self)
        fastDrawAction.triggered.connect(self.fastDraw)
        normalDrawAction = QAction('&Normal draw', self)
        normalDrawAction.triggered.connect(self.normalDraw)
        drawModeMenu.addAction(normalDrawAction)
        drawModeMenu.addAction(fastDrawAction)

        clearHighlightsAction = QAction('&Clear selection', self)
        clearHighlightsAction.setShortcut('Ctrl+C')
        clearHighlightsAction.setStatusTip('Clear highlighted atoms')
        clearHighlightsAction.triggered.connect(self.clearHighlights)
        viewMenu.addAction(clearHighlightsAction)

        clearLabelsAction = QAction('&Clear labels', self)
        clearLabelsAction.setShortcut('Ctrl+Alt+C')
        clearLabelsAction.setStatusTip('Clear labels')
        clearLabelsAction.triggered.connect(self.clearLabels)
        viewMenu.addAction(clearLabelsAction)

        clearUpdateViewAction = QAction('&Clear selection and labels', self)
        clearUpdateViewAction.setShortcut('Ctrl+Shift+C')
        clearUpdateViewAction.setStatusTip('Clear highlighted atoms and labels')
        clearUpdateViewAction.triggered.connect(self.clearUpdateView)
        viewMenu.addAction(clearUpdateViewAction)

        self.showGaussAction = QAction('Show &Gaussian geometry optimization', self)
        self.showGaussAction.setShortcut('Ctrl+G')
        self.showGaussAction.setStatusTip('Show Gaussian geometry optimization plots for energy, force and displacement.')
        self.showGaussAction.setEnabled(False)
        self.showGaussAction.triggered.connect(self.showGauss)
        viewMenu.addAction(self.showGaussAction)
        self.showFreqAction = QAction('Show &IR frequency plot', self)
        self.showFreqAction.setShortcut('Ctrl+I')
        self.showFreqAction.setStatusTip('Show Gaussian calculated IR frequency plot.')
        self.showFreqAction.setEnabled(False)
        self.showFreqAction.triggered.connect(self.showFreq)
        viewMenu.addAction(self.showFreqAction)

        measureDistanceAction = QAction('&Measure &distance', self)
        measureDistanceAction.setShortcut('Ctrl+D')
        measureDistanceAction.setStatusTip('Measure distance between two atoms')
        measureDistanceAction.triggered.connect(self.measureDistanceB)
        measureMenu.addAction(measureDistanceAction)

        measureAngleAction = QAction('&Measure &angle', self)
        measureAngleAction.setShortcut('Ctrl+Shift+D')
        measureAngleAction.setStatusTip('Measure angle between three atoms')
        measureAngleAction.triggered.connect(self.measureAngleB)
        measureMenu.addAction(measureAngleAction)

        aboutAction = QAction('&About', self)
        aboutAction.setStatusTip('About this program...')
        aboutAction.triggered.connect(self.about)
        helpMenu.addAction(aboutAction)

        aboutQtAction = QAction('&About Qt', self)
        aboutQtAction.setStatusTip('About Qt...')
        aboutQtAction.triggered.connect(self.aboutQt)
        helpMenu.addAction(aboutQtAction)

        # define GL widget that displays the 3D molecule model
        self.window = widgets.MyGLView()
        self.window.installEventFilter(self)
        self.window.setMinimumSize(500, 500)
        #self.window.setBackgroundColor((50, 0, 10))
        self.updateView()

        self.gaussianPlot = GraphicsLayoutWidget()
        self.gaussianPlot.resize(750, 250)
        self.gaussianPlot.setWindowTitle('Gaussian geometry optimization')
        #self.gaussianPlot.setAspectLocked(True)
        #self.gaussianPlot.addLayout(rowspan=3, colspan=1)

        self.FreqModel = QStandardItemModel(1, 3, self)
        self.freqTable = QTableView(self)
        self.freqTable.setModel(self.FreqModel)
        self.freqTable.setMinimumWidth(240)
        self.freqTable.installEventFilter(self)
        self.FreqModel.installEventFilter(self)
        self.FreqModel.setHorizontalHeaderLabels(['Frequency','IR Intensity','Raman Intensity'])
        for j, width in enumerate([80, 80, 80]):
            self.freqTable.setColumnWidth(j, width)

        self.freqWidget = QWidget()
        self.freqWidget.setWindowTitle('IR frequency plot & table')
        self.freqWidget.resize(800, 400)
        self.freqWidget.layout = QHBoxLayout(self.freqWidget)
        self.freqWidget.layout.setSpacing(1)
        self.freqWidget.layout.setContentsMargins(1, 1, 1, 1)
        self.freqPlot = GraphicsLayoutWidget()
        self.freqWidget.layout.addWidget(self.freqPlot)
        self.freqWidget.layout.addWidget(self.freqTable)
        self.freqTable.clicked.connect(self.freqCellClicked)

        # define other application parts
        self.statusBar = QStatusBar(self)
        self.fileDialog = QFileDialog(self)

        # define application layout
        self.layout = QVBoxLayout(self)
        self.layout.setSpacing(1)
        self.layout.setContentsMargins(1, 1, 1, 1)
        self.layout1 = QHBoxLayout()
        self.layout1.setSpacing(1)
        self.layout1.addWidget(self.ZMatTable)
        self.layout1.addWidget(self.window)
        self.layout.addWidget(self.menuBar)
        self.layout.addLayout(self.layout1)
        self.layout.addWidget(self.statusBar)

        self.adjustSize()
        self.setWindowTitle('Moldy')
        iconPath = 'icon.png'
        icon = QIcon(iconPath)
        icon.addFile(iconPath, QSize(16, 16))
        icon.addFile(iconPath, QSize(24, 24))
        icon.addFile(iconPath, QSize(32, 32))
        icon.addFile(iconPath, QSize(48, 48))
        icon.addFile(iconPath, QSize(256, 256))
        self.setWindowIcon(icon)

        # start monitoring changes in the ZMatModel
        self.ZMatModel.dataChanged.connect(self.clearUpdateView)

    # run and show the application
    def run(self):
        self.show()
        self.ZMatTable.clicked.connect(self.ZMatCellClicked)
        qt_app.instance().aboutToQuit.connect(self.deleteGLwidget)
        qt_app.exec_()

    # fill the ZMatModel with initial data from 'self.inp'
    def populateZMatModel(self):
        self.ZMatModel.removeRows(0, self.ZMatModel.rowCount())
        for i, row in enumerate(self.inp):
            for j, cell in enumerate(row):
                item = QStandardItem(str(cell))
                self.ZMatModel.setItem(i, j, item)
        # some cells should not be editable, they are disabled
        for i in range(min(len(self.inp), 3)):
            for j in range(2*i+1, 7):
                self.ZMatModel.setItem(i, j, QStandardItem())
                self.ZMatModel.item(i, j).setBackground(QColor(150,150,150))
                self.ZMatModel.item(i, j).setFlags(Qt.ItemIsEnabled)
    
    def populateFreqModel(self):
        self.FreqModel.removeRows(0, self.FreqModel.rowCount())
        for i, row in enumerate(zip(self.vibfreqs, self.vibirs, self.vibramans)):
            for j, cell in enumerate(row):
                item = QStandardItem(str(cell))
                self.FreqModel.setItem(i, j, item)

    # add a row to the bottom of the ZMatModel
    def addRow(self):
        # temporarily stop updating the GL window
        self.ZMatModel.dataChanged.disconnect(self.clearUpdateView)
        row = self.ZMatModel.rowCount()
        self.ZMatModel.insertRow(row)
        # some cells should not be editable
        if row < 3:
            for j in range(2*row+1, 7):
                self.ZMatModel.setItem(row, j, QStandardItem())
                self.ZMatModel.item(row, j).setBackground(QColor(150,150,150))
                self.ZMatModel.item(row, j).setFlags(Qt.ItemIsEnabled)
        # restart GL window updating
        self.ZMatModel.dataChanged.connect(self.clearUpdateView)
        self.statusBar.clearMessage()
        self.statusBar.showMessage('Added 1 row.', 3000)

    # delete the last row of the ZMatModel
    def deleteRow(self):
        xyz = [list(vi) for vi in list(v)]
        atoms = [str(elements[e]) for e in elems]
        oldLen = self.ZMatModel.rowCount()
        idxs = sorted(set(idx.row() for idx in self.ZMatTable.selectedIndexes()), reverse=True)
        newLen = oldLen - len(idxs)
        if newLen == oldLen:
            self.ZMatModel.removeRow(self.ZMatModel.rowCount()-1)
        else:
            self.ZMatModel.dataChanged.disconnect(self.clearUpdateView)
            for idx in idxs:
                self.ZMatModel.removeRow(idx)
                if idx < 3:
                    for i in range(idx, min(3, newLen)):
                        for j in range(2*i+1, 7):
                            self.ZMatModel.setItem(i, j, QStandardItem())
                            self.ZMatModel.item(i, j).setBackground(QColor(150,150,150))
                            self.ZMatModel.item(i, j).setFlags(Qt.ItemIsEnabled)
                if len(xyz) > idx:
                    xyz.pop(idx)
                    atoms.pop(idx)
            self.inp = xyz2zmat(xyz, atoms)
            self.populateZMatModel()
            for i in reversed(self.highList):
                self.window.removeItem(i[1])
            self.highList = []
            self.ZMatModel.dataChanged.connect(self.clearUpdateView)
        self.updateView()
        self.statusBar.clearMessage()
        if idxs:
            self.statusBar.showMessage('Deleted row(s): '+str([i+1 for i in idxs]), 3000)
        else:
            self.statusBar.showMessage('Deleted last row.', 3000)

    # show the periodic table widget
    def periodicTable(self):
        self.statusBar.clearMessage()
        self.statusBar.showMessage('Select element from periodic table.')
        self.periodicTableWidget.exec_()
        selection = self.periodicTableWidget.selection()
        return selection

    # import molecule with zmatrix coordinates
    def readZmat(self):
        self.ZMatModel.dataChanged.disconnect(self.clearUpdateView)
        filename = self.fileDialog.getOpenFileName(self, 'Open file', expanduser('~'), '*.zmat;;*.*')
        self.inp = []
        self.populateZMatModel()
        if filename:
            with open(filename, 'r') as f:
                next(f)
                next(f)
                for row in f:
                    self.inp.append(row.split())
                f.close()
            self.populateZMatModel()
        self.ZMatModel.dataChanged.connect(self.clearUpdateView)
        self.updateView()
        self.statusBar.clearMessage()
        self.statusBar.showMessage('Read molecule from '+filename+'.', 5000)
        self.showGaussAction.setEnabled(False)
        self.showFreqAction.setEnabled(False)

    # import molecule with xyz coordinates
    def readXYZ(self):
        self.ZMatModel.dataChanged.disconnect(self.clearUpdateView)
        filename = self.fileDialog.getOpenFileName(self, 'Open file', expanduser('~'), '*.xyz;;*.*')
        xyz = []
        elems = []
        self.inp = []
        self.populateZMatModel()
        if filename:
            with open(filename, 'r') as f:
                next(f)
                next(f)
                for row in f:
                    rs = row.split()
                    if len(rs) == 4:
                        elems.append(rs[0])
                        xyz.append([float(f) for f in rs[1:]])
                f.close()
            self.inp = xyz2zmat(xyz, elems)
            self.populateZMatModel()
            #print(elems)
        self.ZMatModel.dataChanged.connect(self.clearUpdateView)
        self.updateView()
        self.statusBar.clearMessage()
        self.statusBar.showMessage('Read molecule from '+filename+'.', 5000)
        self.showGaussAction.setEnabled(False)
        self.showFreqAction.setEnabled(False)

    # import Gaussian log file
    def readGaussian(self):
        global vsShifted
        self.ZMatModel.dataChanged.disconnect(self.clearUpdateView)
        filename = self.fileDialog.getOpenFileName(self, 'Open file', expanduser('~'), '*.log;;*.*')
        if filename:
            self.gaussianPlot.clear()
            self.inp = []
            self.populateZMatModel()
            file = ccopen(filename)
            data = file.parse().getattributes()
            self.natom = data['natom']
            self.atomnos = data['atomnos'].tolist()
            self.atomsymbols = [ str(elements[e]) for e in self.atomnos ]
            self.atomcoords = data['atomcoords'].tolist()
            self.scfenergies = data['scfenergies'].tolist()
            self.geovalues = data['geovalues'].T.tolist()
            self.geotargets = data['geotargets'].tolist()
            if 'vibfreqs' in data.keys():
                self.vibfreqs = data['vibfreqs']
                #print(self.vibfreqs)
                self.vibirs = data['vibirs']
                #print(self.vibirs)
                #print(data.keys())
                if 'vibramans' in data.keys():
                    self.vibramans = data['vibramans']
                else:
                    self.vibramans = [''] * len(self.vibirs)
                self.vibdisps = data['vibdisps']
                #print(self.vibdisps)
            self.inp = xyz2zmat(self.atomcoords[0], self.atomsymbols)
            self.populateZMatModel()

            titles = ['SCF Energies', 'RMS & Max Forces', 'RMS & Max Displacements']
            for i in range(3):
                self.gaussianPlot.addPlot(row=1, col=i+1)
                plot = self.gaussianPlot.getItem(1, i+1)
                plot.setTitle(title=titles[i])
                if i == 0:
                    c = ['c']
                    x = [0]
                    y = [self.scfenergies]
                else:
                    c = ['r', 'y']
                    x = [0, 0]
                    y = [self.geovalues[2*i-2], self.geovalues[2*i-1]]
                    targety = [self.geotargets[2*i-2], self.geotargets[2*i-1]]
                plot.clear()
                plot.maxData = plot.plot(y[0], symbol='o', symbolPen=c[0], symbolBrush=c[0], pen=c[0], symbolSize=5, pxMode=True, antialias=True, autoDownsample=False)
                plot.highlight=plot.plot(x, [ yy[0] for yy in y ], symbol='o', symbolPen='w', symbolBrush=None, pen=None, symbolSize=15, pxMode=True, antialias=True, autoDownsample=False)
                plot.maxData.sigPointsClicked.connect(self.gausclicked)
                if i > 0:
                    for j in range(2):
                        plot.addLine(y=np.log10(targety[j]), pen=mkPen((255, 255*j, 0, int(255/2)), width=1))
                    plot.RMSData=plot.plot(y[1], symbol='o', symbolPen=c[1], symbolBrush=c[1], pen=c[1], symbolSize=5, pxMode=True, antialias=True, autoDownsample=False)
                    plot.RMSData.sigPointsClicked.connect(self.gausclicked)
                    plot.setLogMode(y=True)
            self.showGauss()
            self.updateView()
            self.statusBar.clearMessage()
            self.statusBar.showMessage('Read molecule from '+filename+'.', 5000)
            self.ZMatModel.dataChanged.connect(self.clearUpdateView)
            if self.natom:
                self.showGaussAction.setEnabled(True)
            if 'vibfreqs' in data.keys():
                self.showFreqAction.setEnabled(True)

                # populate the FreqModel
                self.populateFreqModel()

                self.freqPlot.clear()
                irPlot = self.freqPlot.addPlot(row=1, col=1)
                irPlot.clear()
                minFreq = np.min(self.vibfreqs)
                maxFreq = np.max(self.vibfreqs)
                maxInt = np.max(self.vibirs)
                x = np.sort(np.concatenate([np.linspace(minFreq-100, maxFreq+100, num=1000), self.vibfreqs]))
                y = x*0
                for f,i in zip(self.vibfreqs, self.vibirs):
                    y += lorentzv(x, f, 2*np.pi, i)
                #xy = np.array([np.concatenate([x, np.array(self.vibfreqs)]), np.concatenate([y, np.array(self.vibirs)])]).T
                #xysort = xy[xy[:,0].argsort()]
                irPlot.maxData = irPlot.plot(x, y, antialias=True)
                markers = ErrorBarItem(x=self.vibfreqs, y=self.vibirs, top=maxInt/30, bottom=None, pen='r')
                irPlot.addItem(markers)
                self.showFreq()
                #self.vibdisps = np.append(self.vibdisps, [np.mean(self.vibdisps, axis=0)], axis=0)
                maxt = 100
                vsShifted = np.array([ [ vs + self.vibdisps[i]*np.sin(t*2*np.pi/maxt)/3 for t in range(maxt) ] for i in range(len(self.vibfreqs)) ])
            else:
                self.showFreqAction.setEnabled(False)
                self.freqWidget.hide()

    def showGauss(self):
        self.gaussianPlot.show()

    def showFreq(self):
        self.freqWidget.show()

    # export Zmatrix to csv
    def writeZmat(self):
        zm = model2list(self.ZMatModel)
        filename = self.fileDialog.getSaveFileName(self, 'Save file', expanduser('~')+'/'+getFormula(list(list(zip(*zm))[0]))+'.zmat', '*.zmat;;*.*')
        try:
            filename
        except NameError:
            pass
        else:
            if filename:
                writeOutput(zm, filename)
                self.statusBar.clearMessage()
                self.statusBar.showMessage('Wrote molecule to '+filename+'.', 5000)

    # export XYZ coordinates to csv
    def writeXYZ(self):
        xyz = []
        zm = model2list(self.ZMatModel)
        for i in range(len(v)):
            xyz.append(np.round(v[i], 7).tolist())
            xyz[i][:0] = zm[i][0]
        if len(v) > 0:
            formula = getFormula(list(list(zip(*xyz))[0]))
        else:
            formula = 'moldy_output'
        filename = self.fileDialog.getSaveFileName(self, 'Save file', expanduser('~')+'/'+formula+'.xyz', '*.xyz;;*.*')
        try:
            filename
        except NameError:
            pass
        else:
            if filename:
                writeOutput(xyz, filename)
                self.statusBar.clearMessage()
                self.statusBar.showMessage('Wrote molecule to '+filename+'.', 5000)

    # redraw the 3D molecule in GL widget
    def updateView(self):
        global r
        global c
        global v
        global vs
        global elems
        global nelems
        data = model2list(self.ZMatModel)
        try:
            # create a list with element coordinates
            v = zmat2xyz(data)
        except (AssertionError, IndexError, ZMError):
            pass
        else:
            # clear the screen before redraw
            for item in reversed(self.window.items):
                self.window.removeItem(item)
            # create a second coordinate list 'vs' that is centered in the GL view
            self.atomList = []
            if len(v) > 0:
                shift = np.mean(v, axis=0)
                vs = np.add(v, -shift)
                elems = [ 1 + next((i for i, sublist in enumerate(colors) if row[0] in sublist), -1) for row in data ]
                nelems = len(elems)
                # define molecule radii and colors
                r = []
                c = []
                for i in elems:
                    r.append(elements[i].covalent_radius)
                    c.append(colors[i-1][-1])
                # draw atoms
                for i in range(nelems):
                    addAtom(self.window, i, r, vs, c, fast=self.fast)
                    self.atomList.append([i, self.window.items[-1]])
                #print(self.atomList)
                # draw bonds where appropriate
                combs = list(itertools.combinations(range(nelems), 2))
                bonds = []
                for i in combs:
                    bonds.append(addBond(self.window, i[0], i[1], r, vs, c, fast=self.fast))
                if self.fast:
                    bondedAtoms = set(filter((None).__ne__, flatten(bonds)))
                    for i in set(range(nelems)) - bondedAtoms:
                        addUnbonded(self.window, i, vs, c)
                        self.atomList[i][1]=self.window.items[-1]
                    #print(self.atomList)

                for i in self.highList:
                    self.window.addItem(i[1])
                for i in self.labelList:
                    self.window.addItem(i)
        if len(v) > 1:
            maxDim = float('-inf')
            for dim in v.T:
                span = max(dim)-min(dim)
                if span > maxDim:
                    maxDim = span
        else: maxDim = 2
        self.window.setCameraPosition(distance=maxDim*1.5+1)

    global index
    index = 0
    def updateFreq(self):
        global vsShifted, index, r, c
        index += 1
        index = index % len(vsShifted[0])
        #print(index)
        #print(vsShifted[index])
        for item in reversed(self.window.items):
            self.window.removeItem(item)
        for i in range(nelems):
            addAtom(self.window, i, r, vsShifted[self.freqIndex, index], c, fast=self.fast)
            self.atomList.append([i, self.window.items[-1]])
        combs = itertools.combinations(range(nelems), 2)
        bonds = []
        for i in combs:
            bonds.append(addBond(self.window, i[0], i[1], r, vsShifted[self.freqIndex, index], c, fast=self.fast))
        if self.fast:
            bondedAtoms = set(filter((None).__ne__, flatten(bonds)))
            for i in set(range(nelems)) - bondedAtoms:
                addUnbonded(self.window, i, vsShifted[self.freqIndex, index], c)
                self.atomList[i][1]=self.window.items[-1]

    # detect mouse clicks in GL window and process them
    def eventFilter(self, obj, event):
        if obj == self.window:
            if event.type() == event.MouseButtonPress:
                itms = obj.itemsAt((event.pos().x()-2, event.pos().y()-2, 4, 4))
                if len(itms):
                    self.highlight(obj, [itms[0]])
                elif len(self.atomList) == 0:
                    self.build()
        # also do the default click action
        return super(MainWidget, self).eventFilter(obj, event)

    def ZMatCellClicked(self):
        idxs = sorted(set(idx.row() for idx in self.ZMatTable.selectedIndexes()), reverse=True)
        itms = []
        if self.highList:
            highIdx = list(np.array(self.highList).T[0])
        for idx in idxs:
            if self.highList and idx in highIdx:
                itms.append(self.highList[highIdx.index(idx)][1])
            elif len(self.atomList) > idx:
                itms.append(self.atomList[idx][1])
        self.highlight(self.window, itms)

    def freqCellClicked(self):
        global vsShifted
        self.timer = QTimer()
        self.timer.setInterval(30)
        self.timer.timeout.connect(self.updateFreq)
        idxs = [ idx.row() for idx in self.freqTable.selectedIndexes() ]
        if len(idxs) == 1:
            self.freqIndex = idxs[0]
            self.timer.stop()
            self.timer.timeout.connect(self.updateFreq)
            try:
                self.ZMatModel.dataChanged.disconnect(self.clearUpdateView)
            except TypeError:
                pass
            self.timer.start()
        if len(idxs) != 1:
            self.timer.stop()
            self.freqTable.clearSelection()
            self.timer.timeout.disconnect(self.updateFreq)
            self.ZMatModel.dataChanged.connect(self.clearUpdateView)
            self.clearUpdateView()

    def gausclicked(self, item, point):
        itemdata = item.scatter.data
        points = [ row[7] for row in itemdata ]
        idx = points.index(point[0])
        for i in range(3):
            if i == 0:
                x = [idx]
                y = [self.scfenergies[idx]]
            else:
                x = [idx, idx]
                y = [self.geovalues[2*i-2][idx], self.geovalues[2*i-1][idx]]
            plot = self.gaussianPlot.getItem(1, i+1)
            plot.removeItem(plot.highlight)
            plot.highlight=plot.plot(x, y, symbol='o', symbolPen='w', symbolBrush=None, pen=None, symbolSize=15, pxMode=True, antialias=True, autoDownsample=False)
        self.ZMatModel.dataChanged.disconnect(self.clearUpdateView)
        self.inp = []
        self.populateZMatModel()
        self.inp = xyz2zmat(self.atomcoords[min(idx, len(self.atomcoords)-1)], self.atomsymbols)
        self.populateZMatModel()
        self.ZMatModel.dataChanged.connect(self.clearUpdateView)
        self.updateView()

    def highlight(self, obj, itms):
        for itm in itms:
            idx = next((i for i, sublist in enumerate(self.atomList) if itm in sublist), -1)
            #print(idx)
            if idx != -1:
                addAtom(obj, idx, r, vs, c, opt='highlight', fast=self.fast)
                self.highList.append([idx, obj.items[-1]])
                self.ZMatTable.selectRow(idx)
            idx = next((i for i, sublist in enumerate(self.highList) if itm in sublist), -1)
            if idx != -1:
                obj.removeItem(self.highList[idx][1])
                self.highList.pop(idx)
                self.ZMatTable.clearSelection()
        self.statusBar.clearMessage()
        if len(self.highList) > 0:
            idxs = np.asarray(self.highList).T[0]
            selected = []
            for i in idxs:
                selected.append(str(i+1)+str(elements[elems[i]]))
            self.statusBar.showMessage('Selected atoms: '+str(selected), 5000)

    def buildB(self):
        try:
            nelems
        except NameError:
            self.build()
        else:
            if len(self.highList) <= min(nelems, 3):
                diff = min(nelems, 3) - len(self.highList)
                if diff != 0:
                    self.statusBar.clearMessage()
                    self.statusBar.showMessage('Please select '+str(diff)+' more atom(s).')
                else:
                    self.build()
            else:
                self.statusBar.clearMessage()
                self.statusBar.showMessage('Too many atoms selected.')

    def build(self):
        selection = self.periodicTable()
        row = self.ZMatModel.rowCount()
        self.addRow()
        self.ZMatModel.dataChanged.disconnect(self.clearUpdateView)
        newSymbol = selection[1]
        newData = [newSymbol]
        if len(self.highList) >= 1:
            newBond = round(2.1*gmean([ elements[e].covalent_radius for e in [selection[0], elems[self.highList[0][0]]] ]), 4)
            newData.append(self.highList[0][0]+1)
            newData.append(newBond)
            if len(self.highList) >= 2:
                newAngle = 109.4712
                newData.append(self.highList[1][0]+1)
                newData.append(newAngle)
                if len(self.highList) == 3:
                    newDihedral = 120.
                    newData.append(self.highList[2][0]+1)
                    newData.append(newDihedral)
        for j, cell in enumerate(newData):
            item = QStandardItem(str(cell))
            self.ZMatModel.setItem(row, j, item)
        self.highList = []
        self.ZMatModel.dataChanged.connect(self.clearUpdateView)
        self.updateView()

    def measureDistanceB(self):
        sel = len(self.highList)
        if sel <= 2:
            if sel < 2:
                self.statusBar.clearMessage()
                self.statusBar.showMessage('Please select '+str(2-sel)+' more atom(s).')
            else:
                self.measureDistance()
        else:
            self.statusBar.clearMessage()
            self.statusBar.showMessage('Too many atoms selected.')

    def measureDistance(self):
        pts = []
        for pt in self.highList:
            pts.append(vs[pt[0]])
        pts = np.array(pts)
        self.clearHighlights()
        line = gl.GLLinePlotItem(pos=pts, color=(0., 1., 0., 1.), width=3)
        self.window.addItem(line)
        self.labelList.append(line)
        q = pts[1]-pts[0]
        dist = round(np.sqrt(np.dot(q, q)), 4)
        self.window.labelPos.append(np.mean(pts[0:2], axis=0))
        self.window.labelText.append(str(dist))
        self.statusBar.clearMessage()
        self.statusBar.showMessage('Measured distance: '+str(dist)+' A.', 3000)

    def measureAngleB(self):
        sel = len(self.highList)
        if sel <= 3:
            if sel < 3:
                self.statusBar.clearMessage()
                self.statusBar.showMessage('Please select '+str(3-sel)+' more atom(s).')
            else:
                self.measureAngle()
        else:
            self.statusBar.clearMessage()
            self.statusBar.showMessage('Too many atoms selected.')

    def measureAngle(self):
        pts = []
        for pt in self.highList:
            pts.append(vs[pt[0]])
        pts = np.array(pts)
        q = pts[1]-pts[0]
        r = pts[2]-pts[0]
        q_u = q / np.sqrt(np.dot(q, q))
        r_u = r / np.sqrt(np.dot(r, r))
        angle = round(degrees(acos(np.dot(q_u, r_u))), 1)
        srange = np.array([slerp(q, r, t) for t in np.arange(0.0, 13/12, 1/12)])
        self.clearHighlights()
        for i in range(12):
            mesh = gl.MeshData(np.array([[0,0,0],srange[i],srange[i+1]]))
            tri = gl.GLMeshItem(meshdata=mesh, smooth=False, computeNormals=False, color=(0.3, 1., 0.3, 0.5), glOptions=('translucent'))
            tri.translate(pts[0][0], pts[0][1], pts[0][2])
            self.window.addItem(tri)
            self.labelList.append(tri)
        self.window.labelPos.append(slerp(q, r, 0.5)+pts[0])
        self.window.labelText.append(str(angle))
        self.statusBar.clearMessage()
        self.statusBar.showMessage('Measured angle: '+str(angle)+'°', 3000)

    def clearLabels(self):
        self.window.labelPos = []
        self.window.labelText = []
        self.labelList = []
        self.updateView()

    def clearHighlights(self):
        for item in reversed(self.highList):
                self.window.removeItem(item[1])
        self.highList = []
        self.updateView()

    def clearUpdateView(self):
        self.window.labelPos = []
        self.window.labelText = []
        self.labelList = []
        for item in reversed(self.highList):
                self.window.removeItem(item[1])
        self.highList = []
        self.updateView()
        #print(self.highList)

    def fastDraw(self):
        if not self.fast:
            self.fast = True
            self.updateView()

    def normalDraw(self):
        if self.fast:
            self.fast = False
            self.updateView()

    def about(self):
        QMessageBox.about(self, 'About moldy', 'moldy beta 15. 9. 2015')

    def aboutQt(self):
        QMessageBox.aboutQt(self, 'About Qt')

    def deleteGLwidget(self):
        self.window.setParent(None)
        del self.window
Example #25
0
class Ui_MainWindow(QMainWindow):
    def __init__(self):
        super(Ui_MainWindow, self).__init__()
        self.traindata = []
        self.traindata4 = []
        self.traindata3 = []
        self.numberofclasses = 0
        self.trueTestDataLabels = []
        self.labeltestdata = []
        self.testData = []
        self.trueTestDataLabels4 = []
        self.labeltestdata4 = []
        self.testData4 = []

        self.trueTestDataLabels3 = []
        self.labeltestdata3 = []
        self.testData3 = []

    def setupUi(self):
        self.centralwidget = QtWidgets.QWidget()

        self.setMinimumSize(QtCore.QSize(1288, 696))
        self.setMaximumSize(QtCore.QSize(1288, 696))

        self.centralwidget.setObjectName("centralwidget")
        self.graphicsView = GraphicsLayoutWidget(self.centralwidget)
        self.graphicsView.setGeometry(QtCore.QRect(10, 80, 751, 321))
        self.graphicsView.setObjectName("graphicsView")
        self.pushButtonExplore = QtWidgets.QPushButton(self.centralwidget)
        self.pushButtonExplore.setGeometry(QtCore.QRect(12, 402, 337, 27))
        self.pushButtonExplore.setObjectName("pushButtonExplore")
        self.graphicsView_2 = GraphicsLayoutWidget(self.centralwidget)
        self.graphicsView_2.setGeometry(QtCore.QRect(10, 440, 751, 221))
        self.graphicsView_2.setObjectName("graphicsView_2")
        self.layoutWidget = QtWidgets.QWidget(self.centralwidget)
        self.layoutWidget.setGeometry(QtCore.QRect(11, 11, 750, 62))
        self.layoutWidget.setObjectName("layoutWidget")
        self.gridLayout = QtWidgets.QGridLayout(self.layoutWidget)
        self.gridLayout.setContentsMargins(0, 0, 0, 0)
        self.gridLayout.setObjectName("gridLayout")
        self.pushButtotLoadIris = QtWidgets.QPushButton(self.layoutWidget)
        self.pushButtotLoadIris.setObjectName("pushButtotLoadIris")
        self.gridLayout.addWidget(self.pushButtotLoadIris, 0, 0, 1, 2)
        self.checkBoxSuspended = QtWidgets.QCheckBox(self.layoutWidget)
        self.checkBoxSuspended.setObjectName("checkBoxSuspended")
        self.gridLayout.addWidget(self.checkBoxSuspended, 0, 2, 1, 3)
        self.pushButtonCheckTest = QtWidgets.QPushButton(self.layoutWidget)
        self.pushButtonCheckTest.setObjectName("pushButtonCheckTest")
        self.gridLayout.addWidget(self.pushButtonCheckTest, 0, 5, 1, 3)
        self.pushButtonGenerate = QtWidgets.QPushButton(self.layoutWidget)
        self.pushButtonGenerate.setObjectName("pushButtonGenerate")
        self.gridLayout.addWidget(self.pushButtonGenerate, 1, 0, 1, 1)
        self.label_3 = QtWidgets.QLabel(self.layoutWidget)
        self.label_3.setObjectName("label_3")
        self.gridLayout.addWidget(self.label_3, 1, 1, 1, 2)
        self.spinBoxClasses = QtWidgets.QSpinBox(self.layoutWidget)
        self.spinBoxClasses.setMinimum(1)
        self.spinBoxClasses.setMaximum(10)
        self.spinBoxClasses.setObjectName("spinBoxClasses")
        self.gridLayout.addWidget(self.spinBoxClasses, 1, 3, 1, 1)
        self.label_2 = QtWidgets.QLabel(self.layoutWidget)
        self.label_2.setObjectName("label_2")
        self.gridLayout.addWidget(self.label_2, 1, 4, 1, 1)
        self.spinBoxElements = QtWidgets.QSpinBox(self.layoutWidget)
        self.spinBoxElements.setMinimum(1)
        self.spinBoxElements.setProperty("value", 20)
        self.spinBoxElements.setObjectName("spinBoxElements")
        self.gridLayout.addWidget(self.spinBoxElements, 1, 5, 1, 1)
        self.label = QtWidgets.QLabel(self.layoutWidget)
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 1, 6, 1, 1)
        self.spinBoxK = QtWidgets.QSpinBox(self.layoutWidget)
        self.spinBoxK.setMinimum(3)
        self.spinBoxK.setSingleStep(2)
        self.spinBoxK.setObjectName("spinBoxK")
        self.gridLayout.addWidget(self.spinBoxK, 1, 7, 1, 1)
        self.graphicsView_3 = GraphicsLayoutWidget(self.centralwidget)
        self.graphicsView_3.setGeometry(QtCore.QRect(790, 80, 441, 311))
        self.graphicsView_3.setObjectName("graphicsView_3")
        self.pushButtonCompare = QtWidgets.QPushButton(self.centralwidget)
        self.pushButtonCompare.setGeometry(QtCore.QRect(790, 40, 361, 31))
        self.pushButtonCompare.setObjectName("pushButtonCompare")

        self.retranslateUi()
        QtCore.QMetaObject.connectSlotsByName(self)
        self.w1 = self.graphicsView.addPlot()
        self.w2 = self.graphicsView_2.addPlot()
        self.w3 = self.graphicsView_3.addPlot()

        self.legend = self.w2.addLegend()
        self.legend1 = self.w3.addLegend()
        self.w1.scene().sigMouseClicked.connect(self.onClick)
        self.pushButtonGenerate.clicked.connect(self.generateDate)
        self.pushButtotLoadIris.clicked.connect(self.loadIris)
        self.pushButtonCheckTest.clicked.connect(self.checkTest)
        self.pushButtonExplore.clicked.connect(self.explore)
        self.pushButtonCompare.clicked.connect(self.compareOptions)

        self.setCentralWidget(self.centralwidget)

    def retranslateUi(self):
        _translate = QtCore.QCoreApplication.translate
        self.pushButtonExplore.setText(
            _translate("MainWindow",
                       "Исследование влияния k для разных метрик"))
        self.pushButtotLoadIris.setText(
            _translate("MainWindow", "Загрузить данные с ирисом"))
        self.checkBoxSuspended.setText(
            _translate("MainWindow", "Использовать взвешенный kNN"))
        self.pushButtonCheckTest.setText(
            _translate("MainWindow", "Проверить тестовую выборку"))
        self.pushButtonGenerate.setText(
            _translate("MainWindow", "Сгенерировать выборку"))
        self.label_3.setText(_translate("MainWindow", "Кол-во классов"))
        self.label_2.setText(_translate("MainWindow", "Кол-во элементов"))
        self.label.setText(_translate("MainWindow", "Кол-во соседей(K)"))
        self.pushButtonCompare.setText(
            _translate("MainWindow",
                       "Сравнить точность от 2,3,4 признаков для ириса"))

    def keyPressEvent(self, e):
        if e.key() == Qt.Key_Escape:
            self.close()
        if e.key() == Qt.Key_Delete:
            self.w1.clear()
            classes = []
            i = 0
            while i < 20:
                classes.append([])
                i += 1

            for i in self.traindata:
                classes[i[1]].append(np.asarray(i[0]))
            i = 0
            for j in classes:
                myS = pg.ScatterPlotItem(size=10,
                                         pen=pg.mkPen(colors[i]),
                                         brush=pg.mkBrush(255, 255, 255, 120))
                myspots = []
                if (len(j)):
                    for k in j:
                        myspots.append({'pos': k, 'data': i})
                    i += 1
                    myS.addPoints(myspots)
                    self.w1.addItem(myS)

    def onClick(self, event):
        if len(self.traindata) == 0:
            return 1
        vb = self.w1.vb
        mousePoint = vb.mapSceneToView(event.scenePos())
        testdata = [[mousePoint.x(), mousePoint.y()]]
        testDataLabels = classifyKNN(self.traindata, testdata,
                                     self.spinBoxK.value(),
                                     self.numberofclasses,
                                     self.checkBoxSuspended.isChecked(), 0)
        myS = pg.ScatterPlotItem(size=10,
                                 pen=pg.mkPen(colors[testDataLabels[0]]),
                                 brush=pg.mkBrush(255, 255, 255, 120))
        myspots = []
        myspots.append({
            'pos': np.asarray([mousePoint.x(), mousePoint.y()]),
            'data': testDataLabels[0]
        })
        myS.addPoints(myspots)
        self.w1.addItem(myS)
        self.traindata.append([[mousePoint.x(), mousePoint.y()],
                               testDataLabels[0]])
        print(self.traindata)

    def loadIris(self):
        self.w1.clear()
        self.traindata = []
        self.traindata4 = []
        self.traindata3 = []

        self.trueTestDataLabels = []
        self.labeltestdata = []
        self.testData = []
        self.trueTestDataLabels4 = []
        self.labeltestdata4 = []
        self.testData4 = []

        self.trueTestDataLabels3 = []
        self.labeltestdata3 = []
        self.testData3 = []

        from sklearn.datasets import load_iris
        train = load_iris().data
        labels = load_iris().target
        self.traindata4 = []
        n = 0
        for i in train:
            self.traindata4.append([])
            self.traindata4[n].append(i.tolist())
            self.traindata4[n].append(labels[n])
            n += 1

        # testDataLabels = classifyKNN(trainData, testData, 5, 2)

        trainData4, self.trueTestDataLabels4 = splitTrainTest(
            self.traindata4, 0.33)

        self.traindata4 = trainData4
        self.testData4 = [
            self.trueTestDataLabels4[i][0]
            for i in range(len(self.trueTestDataLabels4))
        ]
        #  self.labeltestdata = classifyKNN(trainData, self.testData, self.spinBoxK.value(), self.numberofclasses,self.checkBoxSuspended.isChecked())
        for i in trainData4:
            self.traindata3.append([i[0][:-1], i[1]])

        print(self.traindata3)
        #  self.labeltestdata = classifyKNN(trainData, self.testData, self.spinBoxK.value(), self.numberofclasses,self.checkBoxSuspended.isChecked())
        for i in self.testData4:
            self.testData3.append(i[:-1])
            print(i[:-1])

        for i in self.trueTestDataLabels4:
            self.trueTestDataLabels3.append([i[0][:-1], i[1]])
        classes = []
        i = 0
        for i in trainData4:
            self.traindata.append([i[0][:-2], i[1]])

        print(self.traindata3)
        #  self.labeltestdata = classifyKNN(trainData, self.testData, self.spinBoxK.value(), self.numberofclasses,self.checkBoxSuspended.isChecked())
        for i in self.testData4:
            self.testData.append(i[:-2])
            print(i[:-1])

        for i in self.trueTestDataLabels4:
            self.trueTestDataLabels.append([i[0][:-2], i[1]])
        i = 0
        while i < 20:
            classes.append([])
            i += 1

        for i in self.traindata:
            classes[i[1]].append(np.asarray(i[0]))
        i = 0
        for j in classes:
            myS = pg.ScatterPlotItem(size=10,
                                     pen=pg.mkPen(colors[i]),
                                     brush=pg.mkBrush(255, 255, 255, 120))
            myspots = []
            if (len(j)):
                for k in j:
                    myspots.append({'pos': k, 'data': i})
                i += 1
                myS.addPoints(myspots)
                self.w1.addItem(myS)
        self.spinBoxClasses.setValue(3)
        self.spinBoxK.setValue(4)
        self.spinBoxK.setSingleStep(3)
        self.spinBoxElements.setValue(75)
        self.spinBoxClasses.setValue(3)
        self.numberofclasses = 3

    def checkTest(self):
        if len(self.traindata) == 0:
            return 1
        print(self.testData)
        self.labeltestdata = classifyKNN(self.traindata, self.testData,
                                         self.spinBoxK.value(),
                                         self.numberofclasses,
                                         self.checkBoxSuspended.isChecked(), 0)
        x = sum([
            int(self.labeltestdata[i] == self.trueTestDataLabels[i][1])
            for i in range(len(self.trueTestDataLabels))
        ]) / float(len(self.trueTestDataLabels))

        classes = []
        i = 0
        while i < 20:
            classes.append([])
            i += 1

        for i in self.trueTestDataLabels:
            classes[i[1]].append(np.asarray(i[0]))
        i = 0
        for j in classes:
            myS = pg.ScatterPlotItem(size=10,
                                     pen=pg.mkPen(colors[i]),
                                     brush=pg.mkBrush(255, 255, 255, 120))
            myspots = []
            if (len(j)):
                for k in j:
                    myspots.append({'pos': k, 'data': i})
                i += 1
                myS.addPoints(myspots)
                self.w1.addItem(myS)

        dialog = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Information,
                                       "Точность классификации ",
                                       str(x),
                                       buttons=QtWidgets.QMessageBox.Ok,
                                       parent=None)
        result = dialog.exec_()

    def changeK(self, i):

        self.spinBoxK.setSingleStep(i)
        self.spinBoxK.setMinimum(i + 1)
        self.spinBoxK.setProperty("value", i + 1)

    def generateDate(self):
        self.w1.clear()
        data = generateData(self.spinBoxElements.value(),
                            self.spinBoxClasses.value())
        self.numberofclasses = self.spinBoxClasses.value()
        trainData, self.trueTestDataLabels = splitTrainTest(data, 0.33)

        self.traindata = trainData
        self.testData = [
            self.trueTestDataLabels[i][0]
            for i in range(len(self.trueTestDataLabels))
        ]
        # self.labeltestdata = classifyKNN(trainData, self.testData, self.spinBoxK.value(), self.numberofclasses,self.checkBoxSuspended.isChecked())

        classes = []
        i = 0
        while i < 20:
            classes.append([])
            i += 1

        for i in trainData:
            classes[i[1]].append(np.asarray(i[0]))
        i = 0
        for j in classes:
            myS = pg.ScatterPlotItem(size=10,
                                     pen=pg.mkPen(colors[i]),
                                     brush=pg.mkBrush(255, 255, 255, 120))
            myspots = []
            if (len(j)):
                for k in j:
                    myspots.append({'pos': k, 'data': i})
                i += 1
                myS.addPoints(myspots)
                self.w1.addItem(myS)

    def explore(self):
        if not (self.traindata):
            return
        trainData = []
        testData = []

        trueTestDataLabels = []
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Information)

        msg.setWindowTitle("Выбор количества признаков")
        msg.setText("Privet")

        twoOptions = msg.addButton('2 признака', QMessageBox.AcceptRole)
        threeOptions = msg.addButton('3 признака', QMessageBox.AcceptRole)
        fourOptions = msg.addButton('4 признака', QMessageBox.AcceptRole)

        msg.exec()
        if msg.clickedButton() == twoOptions:
            trainData = self.traindata
            testData = self.testData

            trueTestDataLabels = self.trueTestDataLabels
        elif msg.clickedButton() == threeOptions:
            trainData = self.traindata3
            testData = self.testData3

            trueTestDataLabels = self.trueTestDataLabels3
        elif msg.clickedButton() == fourOptions:
            trainData = self.traindata4
            testData = self.testData4

            trueTestDataLabels = self.trueTestDataLabels4
        self.w2.clear()
        self.legend.scene().removeItem(self.legend)
        self.legend = self.w2.addLegend((20, 20), (420, 20))
        myspots = []
        i = self.spinBoxK.value()
        while i < self.spinBoxElements.value():
            labeltestdata = classifyKNN(trainData, testData, i,
                                        self.numberofclasses,
                                        self.checkBoxSuspended.isChecked(), 0)
            myspots.append([
                i,
                sum([
                    int(labeltestdata[i] == trueTestDataLabels[i][1])
                    for i in range(len(trueTestDataLabels))
                ]) / float(len(trueTestDataLabels))
            ])
            i += self.spinBoxK.singleStep()
        self.w2.plot(
            x=[x[0] for x in myspots],
            y=[y[1] for y in myspots],
            symbol='o',
            name="Евклидово расстояние",
            pen=(0, 0, 255),
        )

        myspots = []
        i = self.spinBoxK.value()
        while i < self.spinBoxElements.value():
            labeltestdata = classifyKNN(trainData, testData, i,
                                        self.numberofclasses,
                                        self.checkBoxSuspended.isChecked(), 1)
            myspots.append([
                i,
                sum([
                    int(labeltestdata[i] == trueTestDataLabels[i][1])
                    for i in range(len(trueTestDataLabels))
                ]) / float(len(trueTestDataLabels))
            ])
            i += self.spinBoxK.singleStep()
        self.w2.plot(x=[x[0] for x in myspots],
                     y=[y[1] for y in myspots],
                     pen=(255, 0, 0),
                     symbolBrush=(255, 0, 0),
                     symbolPen='w',
                     name="Манхэттенское расстояние")
        myspots = []
        i = self.spinBoxK.value()
        while i < self.spinBoxElements.value():
            labeltestdata = classifyKNN(trainData, testData, i,
                                        self.numberofclasses,
                                        self.checkBoxSuspended.isChecked(), 2)
            myspots.append([
                i,
                sum([
                    int(labeltestdata[i] == trueTestDataLabels[i][1])
                    for i in range(len(trueTestDataLabels))
                ]) / float(len(trueTestDataLabels))
            ])
            i += self.spinBoxK.singleStep()
        self.w2.plot(x=[x[0] for x in myspots],
                     y=[y[1] for y in myspots],
                     pen=(0, 255, 0),
                     symbolBrush=(0, 255, 0),
                     symbolPen='g',
                     name="Расстояние Чебышева")
        self.w2.setLabels(title='Сравнение метрик',
                          left="Точность",
                          bottom="K")

        self.setMinimumSize(QtCore.QSize(1288, 717))
        self.setMaximumSize(QtCore.QSize(1288, 717))

        #self.w2.plot(myspots, pen=(200, 200, 200), symbolBrush=(255, 0, 0), symbolPen='w')

    def compareOptions(self):
        if not (self.traindata):
            return
        self.w3.clear()
        self.legend1.scene().removeItem(self.legend1)
        self.legend1 = self.w3.addLegend((20, 20), (20, 0))
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Information)

        msg.setWindowTitle("Выбор метрики")
        msg.setText("Privet")

        twoOptions = msg.addButton('Евклидово расстояние',
                                   QMessageBox.AcceptRole)
        threeOptions = msg.addButton('Манхэттенское расстояние',
                                     QMessageBox.AcceptRole)
        fourOptions = msg.addButton('Расстояние Чебышева',
                                    QMessageBox.AcceptRole)

        msg.exec()
        if msg.clickedButton() == twoOptions:
            metrick = 0
        elif msg.clickedButton() == threeOptions:
            metrick = 1
        elif msg.clickedButton() == fourOptions:
            metrick = 2
        myspots = []
        i = self.spinBoxK.value()
        while i < self.spinBoxElements.value():
            self.labeltestdata4 = classifyKNN(
                self.traindata4, self.testData4, i, self.numberofclasses,
                self.checkBoxSuspended.isChecked(), metrick)
            myspots.append([
                i,
                sum([
                    int(self.labeltestdata4[i] == self.trueTestDataLabels4[i]
                        [1]) for i in range(len(self.trueTestDataLabels4))
                ]) / float(len(self.trueTestDataLabels4))
            ])
            i += self.spinBoxK.singleStep()
        self.w3.plot(x=[x[0] for x in myspots],
                     y=[y[1] for y in myspots],
                     pen=(0, 255, 0),
                     symbolBrush=(0, 255, 0),
                     symbolPen='g',
                     name="Четыре признака")
        self.w3.setLabels(title='Сравнение точности в зависимости от признака',
                          left="Точность",
                          bottom="K")

        myspots = []
        i = self.spinBoxK.value()
        while i < self.spinBoxElements.value():
            self.labeltestdata3 = classifyKNN(
                self.traindata3, self.testData3, i, self.numberofclasses,
                self.checkBoxSuspended.isChecked(), metrick)
            myspots.append([
                i,
                sum([
                    int(self.labeltestdata3[i] == self.trueTestDataLabels3[i]
                        [1]) for i in range(len(self.trueTestDataLabels3))
                ]) / float(len(self.trueTestDataLabels3))
            ])
            i += self.spinBoxK.singleStep()
        self.w3.plot(x=[x[0] for x in myspots],
                     y=[y[1] for y in myspots],
                     pen=(0, 255, 0),
                     symbolBrush=(0, 0, 255),
                     symbol='o',
                     name="Три признака")
        self.w3.setLabels(title='Сравнение точности в зависимости от признака',
                          left="Точность",
                          bottom="K")

        myspots = []
        i = self.spinBoxK.value()
        while i < self.spinBoxElements.value():
            self.labeltestdata = classifyKNN(
                self.traindata, self.testData, i, self.numberofclasses,
                self.checkBoxSuspended.isChecked(), metrick)
            myspots.append([
                i,
                sum([
                    int(self.labeltestdata[i] == self.trueTestDataLabels[i][1])
                    for i in range(len(self.trueTestDataLabels))
                ]) / float(len(self.trueTestDataLabels))
            ])
            i += self.spinBoxK.singleStep()
        self.w3.plot(x=[x[0] for x in myspots],
                     y=[y[1] for y in myspots],
                     pen=(255, 0, 0),
                     symbolBrush=(255, 0, 0),
                     symbolPen='w',
                     name="Два признака")
        self.w3.setLabels(title='Сравнение точности в зависимости от признака',
                          left="Точность",
                          bottom="K")