Beispiel #1
0
class PlotWidget(QtWidgets.QWidget):
	def __init__(self, parent=None):
		QtWidgets.QWidget.__init__(self, parent)
		self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
		
		self.figure = plt.figure()
		
		self.canvas = FigureCanvas(self.figure)
		
		self.toolbar = NavigationToolbar(self.canvas, self)
		
		self.button = QtWidgets.QPushButton("Plot")
		self.button.clicked.connect(self.plot)
		
		layout = QtWidgets.QVBoxLayout()
		layout.addWidget(self.toolbar)
		layout.addWidget(self.canvas)
		layout.addWidget(self.button)
		
		self.setLayout(layout)
	
	def plot(self):
		data = [x for x in range(10)]
		
		ax = self.figure.add_subplot(111)
		
		ax.hold(False)
		
		ax.plot(data, "*-")
		
		self.canvas.draw()
Beispiel #2
0
class ColorbarWidget(QWidget):

    def __init__(self, parent=None):
        super(ColorbarWidget, self).__init__(parent)
        fig = Figure()
        rect = 0.25, 0.05, 0.1, 0.90
        self.cb_axes = fig.add_axes(rect)
        self.canvas = FigureCanvas(fig)
        self.setLayout(QVBoxLayout())
        self.layout().addWidget(self.canvas)
        self.button = QPushButton("Update")
        self.layout().addWidget(self.button)
        self.button.pressed.connect(self._update_cb_scale)

        self._create_colorbar(fig)

    def _create_colorbar(self, fig):
        self.mappable = ScalarMappable(norm=SymLogNorm(0.0001, 1,vmin=-10., vmax=10000.),
                                  cmap=DEFAULT_CMAP)
        self.mappable.set_array([])
        fig.colorbar(self.mappable, ax=self.cb_axes, cax=self.cb_axes)

    def _update_cb_scale(self):
        self.mappable.colorbar.remove()
        rect = 0.25, 0.05, 0.1, 0.90
        self.cb_axes = self.canvas.figure.add_axes(rect)
        self.mappable = ScalarMappable(Normalize(30, 4300),
                                   cmap=DEFAULT_CMAP)
        self.mappable.set_array([])
        self.canvas.figure.colorbar(self.mappable, ax=self.cb_axes, cax=self.cb_axes)
        self.canvas.draw()
Beispiel #3
0
class Statistics():
    def __init__(self, stat_label, parent, width=3, height=4, dpi=100):

        self.fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = self.fig.add_subplot(111)
        self.axes.hold(False)

        self.canvas = FigureCanvasQTAgg(self.fig)
        parent.addWidget(self.canvas, 1, 0, 1, 1)

        self.canvas.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding)
        self.canvas.updateGeometry()

        self.stat_label = stat_label;
        self.reset()

    def refresh(self, stats):
        # stats.print()
        _translate = QtCore.QCoreApplication.translate
        self.stat_label.setText(_translate("MainWindow", stats.print()))
        # counters
        foodCnt = stats.foodCnt()
        self.foods.append(foodCnt.existing)
        self.stepNumbers.append(stats.stepNumber())
        # plot
        self.axes.plot(self.stepNumbers, self.foods)
        self.axes.set_xlabel("Step number")
        self.axes.set_ylabel("Food count")
        self.canvas.draw()

    def reset(self):
        self.foods = []
        self.stepNumbers = []
Beispiel #4
0
class Window(QDialog):
#    https://stackoverflow.com/questions/12459811/how-to-embed-matplotlib-in-pyqt-for-dummies
    
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        # a figure instance to plot on
        self.figure = plt.figure()

        # this is the Canvas Widget that displays the `figure`
        # it takes the `figure` instance as a parameter to __init__
        self.canvas = FigureCanvas(self.figure)

        # this is the Navigation widget
        # it takes the Canvas widget and a parent
        self.toolbar = NavigationToolbar(self.canvas, self)

        # Just some button connected to `plot` method
        self.button = QPushButton('Plot')
        self.button.clicked.connect(self.plot)

        # set the layout
        layout = QVBoxLayout()
        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)
        layout.addWidget(self.button)
        self.setLayout(layout)

    def plot(self):
        ''' plot some random stuff '''
        # random data
        data = [random.random() for i in range(10)]

        # instead of ax.hold(False)
        self.figure.clear()

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

        # discards the old graph
        # ax.hold(False) # deprecated, see above

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

        # refresh canvas
        self.canvas.draw()

    def keyPressEvent(self, event):
        
        # http://zetcode.com/gui/pyqt5/eventssignals/
        
      if event.key() == QtCore.Qt.Key_Escape:
         self.close()
      if event.key() == QtCore.Qt.Key_Space:
        global gridLayout
        item = gridLayout.itemAtPosition(1,1)
        w = item.widget()
        w.setText("test")
Beispiel #5
0
class RadarUI(QtWidgets.QWidget):
# class RadarUI(QtWidgets.QMainWindow):

    def __init__(self):
        super(RadarUI, self).__init__()
        self.__controller = None
        self.__init_ui()

    def __init_ui(self):
        remove_clutter = QtWidgets.QPushButton('Remove Clutter', self)
        restore_clutter = QtWidgets.QPushButton('Restore Clutter', self)

        remove_clutter.clicked.connect(self.remove_clutter)
        restore_clutter.clicked.connect(self.restore_clutter)

        buttons_layout = QtWidgets.QHBoxLayout()
        buttons_layout.addWidget(remove_clutter)
        buttons_layout.addWidget(restore_clutter)

        figure = Figure()
        self.__controller = controller.Controller(figure)
        self.__controller.update.connect(self.__update_label)

        ax = figure.add_subplot(212)
        self.__line, = ax.plot(range(10))

        self.__canvas = FigureCanvasQTAgg(figure)
        self.__canvas.show()

        self.__name_label = QtWidgets.QLabel("asdf")

        # main layout
        main_layout = QtWidgets.QVBoxLayout()
        main_layout.addStretch(1)
        main_layout.addWidget(self.__canvas)
        main_layout.addWidget(self.__name_label)
        main_layout.addLayout(buttons_layout)

        self.setLayout(main_layout)
        self.show()

    def remove_clutter(self):
        # todo
        x, y = self.__line.get_data()
        self.__line.set_ydata(y - 0.2 * x)
        self.__canvas.draw()

    def restore_clutter(self):
        # todo
        x, y = self.__line.get_data()
        self.__line.set_ydata(y + 0.2 * x)
        self.__canvas.draw()

    def run(self):
        self.__controller.run2()

    @QtCore.pyqtSlot(np.ndarray)
    def __update_label(self, value):
        self.__name_label.setText(str(value))
Beispiel #6
0
class MainWindow(QMainWindow, Ui_MainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()
        self.setupUi(self)
        self.setWindowTitle('Fit Window')

        self._create_mplplot()
        self._peak_picker = self._create_peak_picker(self._canvas)

        self._onpick = self._canvas.mpl_connect('pick_event',
                                                self._on_pick)


    def _create_mplplot(self):
        x = np.arange(1,101, 0.01)
        mu, sigma = 50, 5
        y = np.exp( - (x - mu)**2 / (2 * sigma**2))
        fig = Figure()
        axes = fig.add_subplot(111)
        axes.plot(x, y, color='black')
        axes.set_title('Text', y=1.02)

        self._canvas = FigureCanvas(fig)
        print(dir(FigureCanvas))
        self._filter = MouseClickMonitor(self._canvas)
        self._canvas.installEventFilter(self._filter)
        self.mpllayout.addWidget(self._canvas)
        self._canvas.draw()
        return fig

    def _create_peak_picker(self, canvas):
        picker = PeakPickerTool(canvas)
        self.on_region_update(picker.lines[0].get_xdata()[0],
                              picker.lines[1].get_xdata()[0])
        picker.region_updated.connect(self.on_region_update)
        return picker

    def _on_pick(self, evt):
        if not evt.mouseevent.dblclick:
            return
        print(dir(evt.artist.get_text()))
        # print("Title double clicked at matplotlib coords",evt.mouseevent.x, evt.mouseevent.y)
        # print("Canvas width=",self._canvas.width(), "height=", self._canvas.height())
        # editor = QLineEdit(self._canvas)
        # editor.setAttribute(Qt.WA_DeleteOnClose)
        # editor.setText(self._canvas.figure.get_axes()[0].get_title())
        # self._canvas.figure.get_axes()[0].set_title('')
        # self._canvas.draw()
        # editor.move(evt.mouseevent.x - (0.5*editor.width()), self._canvas.height() - evt.mouseevent.y - 0.5*editor.height())
        # editor.show()
        # self._editor = editor


    def on_region_update(self, leftx, rightx):
        self.table_widget.setItem(0, 1, QTableWidgetItem(str(leftx)))
        self.table_widget.setItem(1, 1, QTableWidgetItem(str(rightx)))
def test_resize_qt():

    # This test just ensures that the code runs, but doesn't check for now
    # that the behavior is correct.

    pytest.importorskip('PyQt5')

    from PyQt5.QtWidgets import QMainWindow

    from matplotlib.figure import Figure
    from matplotlib.backends.backend_qt5 import FigureManagerQT
    from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg

    fig = Figure()
    canvas = FigureCanvasQTAgg(fig)
    canvas.manager = FigureManagerQT(canvas, 0)  # noqa
    ax = fig.add_subplot(1, 1, 1)

    canvas.draw = Mock(side_effect=canvas.draw)

    from matplotlib.backends.backend_qt5 import qApp

    window = QMainWindow()
    window.setCentralWidget(canvas)
    window.show()

    x1 = np.random.normal(0, 1, 10000000)
    y1 = np.random.normal(0, 1, 10000000)

    a = ScatterDensityArtist(ax, x1, y1)
    ax.add_artist(a)

    canvas.draw()
    assert not a.stale
    assert canvas.draw.call_count == 1

    window.resize(300, 300)

    # We can't actually check that stale is set to True since it only remains
    # so for a short amount of time, but we can check that draw is called twice
    # (once at the original resolution then once with the updated resolution).
    start = time.time()
    while time.time() - start < 1:
        qApp.processEvents()

    assert canvas.draw.call_count == 3

    assert not a.stale

    start = time.time()
    while time.time() - start < 1:
        qApp.processEvents()

    a.remove()
    qApp.processEvents()
class PlotFigure(object):
    signals = []
    canvas = None

    def __init__(self, parent=None):
        self.fig = Figure(figsize=(600, 600),
                          dpi=72,
                          facecolor=(1, 1, 1),
                          edgecolor=(0, 0, 0))
        self.canvas = FigureCanvas(self.fig)

    def addSeries(self, series):
        self.rmSeries(series)
        # Add a new series
        if self.signals:
            if((self.signals[0].xunits == series.xunits) and
               (self.signals[0].yunits == series.yunits)):
                self.signals.append(series)
            else:
                self.signals = [series]
        else:
            self.signals = [series]

    def rmSeries(self, series):
        if self.signals:
            try:
                self.signals.remove(series)
            except:
                pass

    def clearSeries(self):
        self.signals = []

    def draw(self):
        self.ax = self.fig.add_subplot(1, 1, 1)
        self.ax.cla()
        for s in self.signals:
            self.ax.plot(s.xvalues, s.data, label=s.label)
        if len(self.signals):
            self.ax.set_xlabel(self.signals[0].xunits)
            self.ax.set_ylabel(self.signals[0].yunits)

        handles, labels = self.ax.get_legend_handles_labels()
        self.ax.legend(handles[::-1], labels[::-1])
        self.ax.legend(handles, labels)

        try:
            self.plotExtras()
        except:
            pass

        self.canvas.draw()

    def getWidget(self):
        return self.canvas
class MainWindow(QWidget):

    updGUI=pyqtSignal()
    def __init__(self, pose3d, parent=None):
        super(MainWindow, self).__init__(parent)
        
        layout = QGridLayout()
        
        self.seconds = 0
        self.MAXseconds = 900
        self.contSeconds = 0
        self.secondsArray = [0]
        
        self.devPercentajes = [0]
        self.percentaje = porcentajeWidget(self, pose3d)
        self.percentajePrev = 0
        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure)
        
        layout.addWidget(self.canvas)
        
        vSpacer = QSpacerItem(30, 50, QSizePolicy.Ignored, QSizePolicy.Ignored)
        layout.addItem(vSpacer,1,0)
        
        self.setFixedSize(1200,500);
        
        self.setLayout(layout)
        
        timer = QTimer(self)
        timer.start(1000)
        timer.timeout.connect(self.contadorTime)
        

    def contadorTime(self):
        if self.seconds < self.MAXseconds:
            self.percentaje.updateG()
            self.seconds += 1
            if self.seconds % 2 == 0:
                self.contSeconds += 1
                dif = float(float(self.percentaje.porcentajeCasa) - float(self.percentajePrev))
                self.devPercentajes.append(dif)
                self.secondsArray.append(self.contSeconds)
                self.percentajePrev = self.percentaje.porcentajeCasa
            
            ax = self.figure.add_subplot(111)
            ax.set_xlabel('Time')
            ax.set_ylabel('Percentage Derivative')
            ax.set_xlim([0, 450]);
            ax.set_ylim([0, 0.7]);
            ax.plot(self.secondsArray, self.devPercentajes,'r')
            self.canvas.draw()
Beispiel #10
0
class MyWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.setupUI()

    def setupUI(self):
        self.setGeometry(600, 200, 1200, 600)
        self.setWindowTitle("PyChart Viewer v0.1")
        self.setWindowIcon(QIcon('icon.png'))

        self.lineEdit = QLineEdit()
        self.pushButton = QPushButton("차트그리기")
        self.pushButton.clicked.connect(self.pushButtonClicked)

        self.fig = plt.Figure()
        self.canvas = FigureCanvas(self.fig)

        leftLayout = QVBoxLayout()
        leftLayout.addWidget(self.canvas)

        # Right Layout
        rightLayout = QVBoxLayout()
        rightLayout.addWidget(self.lineEdit)
        rightLayout.addWidget(self.pushButton)
        rightLayout.addStretch(1)

        layout = QHBoxLayout()
        layout.addLayout(leftLayout)
        layout.addLayout(rightLayout)
        layout.setStretchFactor(leftLayout, 1)
        layout.setStretchFactor(rightLayout, 0)

        self.setLayout(layout)

    def pushButtonClicked(self):
        code = self.lineEdit.text()
        df = web.DataReader(code, "yahoo")
        df['MA20'] = df['Adj Close'].rolling(window=20).mean()
        df['MA60'] = df['Adj Close'].rolling(window=60).mean()

        ax = self.fig.add_subplot(111)
        ax.plot(df.index, df['Adj Close'], label='Adj Close')
        ax.plot(df.index, df['MA20'], label='MA20')
        ax.plot(df.index, df['MA60'], label='MA60')
        ax.legend(loc='upper right')
        ax.grid()

        self.canvas.draw()
Beispiel #11
0
class PlotWidget(QtWidgets.QFrame):

    SStats = pyqtSignal(np.ndarray, np.ndarray, np.ndarray, np.ndarray,
                        np.ndarray, np.ndarray)

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

    def initUI(self):
        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure)
        self.toolbar = NavigationToolbar(self.canvas, self)

        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)
        self.setLayout(layout)

    def plot_sounding_axes(self):
        self.figure.clear()
        ax = self.figure.add_axes([0.05, 0.05, 0.90, 0.945])
        # ax = self.figure.add_axes([0.005,0.05,0.985,0.945])
        ax.hold(True)
        skewt.set_fontscalefactor(4)
        skewt.plot_sounding_axes(ax)
        self.canvas.draw()

    def plot_hodograph_axes(self):
        ax = self.figure.add_axes([0.005, 0.005, 0.985, 0.985])
        ax.hold(True)
        skewt.plot_hodo_axes(ax)
        self.canvas.draw()

    def plot_sounding(self, z, th, p, qv, u, v):
        self.figure.clear()
        # ax = self.figure.add_axes([0.005,0.05,0.985,0.945])
        ax = self.figure.add_axes([0.05, 0.05, 0.90, 0.945])
        ax.hold(True)
        skewt.plot_sounding_axes(ax)
        skewt.plot_sounding(ax, z, th, p, qv, u, v)
        self.canvas.draw()
        # Send data to stats widget
        self.SStats.emit(z, th, p, qv, u, v)

    def plot_hodograph(self, z, u, v):
        self.figure.clear()
        ax = self.figure.add_axes([0.005, 0.05, 0.985, 0.945])
        ax.hold(True)
        skewt.plot_hodo_axes(ax)
        skewt.plot_hodograph(ax, z, u, v)
        self.canvas.draw()
Beispiel #12
0
class Window(QtWidgets.QDialog):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        # a figure instance to plot on
        self.figure = plt.figure()

        # this is the Canvas Widget that displays the `figure`
        # it takes the `figure` instance as a parameter to __init__
        self.canvas = FigureCanvas(self.figure)

        # this is the Navigation widget
        # it takes the Canvas widget and a parent
        self.toolbar = NavigationToolbar(self.canvas, self)

        # Just some button connected to `plot` method
        self.button = QtWidgets.QPushButton('Plot')
        self.button.clicked.connect(self.plot)

        # set the layout
        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)
        layout.addWidget(self.button)
        self.setLayout(layout)

    def plot(self):
        ''' plot some random stuff '''
        # random data
        data = [random.random() for i in range(10)]

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

        # discards the old graph
        ax.hold(False)

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

        # refresh canvas
        self.canvas.draw()
Beispiel #13
0
    def detach_plot(self):
        new_window = QtWidgets.QMainWindow(self)
        new_window.setWindowTitle('Graphique détaché')

        frame = QtWidgets.QFrame(new_window)

        canvas = FigureCanvas(self.figure)
        canvas.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        canvas.updateGeometry()
        canvas.draw()

        toolbar = NavigationToolbar(canvas, frame)

        layout = QtWidgets.QVBoxLayout(frame)
        layout.addWidget(canvas, 1)
        layout.addWidget(toolbar, 0)

        new_window.setCentralWidget(frame)
        new_window.show()

        return new_window
Beispiel #14
0
class SensorWidget():
    # ToDo: Add signal to this object and emit value each time new value
    # is taken from queue
    def __init__(self, parent=None):
        self.figure, self.axes = plt.subplots()
        self.x_axis = []
        self.y_values = []
        self.sensor_plot_queue = Queue(maxsize=N_POINTS_ON_PLOT)

        self.compute_initial_figure()
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setParent(parent)

        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.update_figure)
        self.timer.start(50)

    def compute_initial_figure(self):
        self.axes.plot(self.y_values)

    def feed_value(self, value):
        self.sensor_plot_queue.put(value)

    def update_figure(self):
        self.axes.cla()
        # ToDo: Need to add lock here and iterate through all elements
        if not self.sensor_plot_queue.empty():
            self.y_values.append(self.sensor_plot_queue.get())
        if len(self.y_values) > N_POINTS_ON_PLOT:
            self.y_values.pop(0)
            self.x_axis = [x + 1 for x in self.x_axis]
        else:
            self.axes.set_xlim(0, N_POINTS_ON_PLOT)
            while len(self.x_axis) < len(self.y_values):
                self.x_axis.append(len(self.y_values))
        self.axes.plot(self.x_axis, self.y_values, ".")
        self.axes.plot(self.x_axis, self.y_values, "-")
        logging.debug("Drawing new plot")
        self.canvas.draw()
Beispiel #15
0
class fcHistogram(QDialog, Ui_histwin):
    def __init__(self, parent=None):
        super(fcHistogram, self).__init__(parent)
        self.setupUi(self)
        fig1 = Figure()
        self.canvas = FigureCanvas(fig1)
        self.histogram.addWidget(self.canvas)
        self.plot = fig1.add_subplot(111)
        self.plot.set_ylim([0, 5000])
        self.plot.set_xlim([0, 256])
        self.canvas.draw()
        
    def setupThreadingUpdates(self, imgthread):
        #set up connections to UI update from imgthread
        imgthread.displayWashoutsSig.connect(self.displayWashouts)
        imgthread.plotHistogramSig.connect(self.plotHistogram)

    def displayWashouts(self, over, px, avg): #in hindsight, is this really useful?
        logging.debug("DisplayWashouts Called")
        logging.debug(over[1])
        logging.debug(avg)
        logging.debug(px)
        self.pctOverB.setText(adj_for_size(over[0], px))
        self.pctOverG.setText(adj_for_size(over[1], px))
        self.pctOverR.setText(adj_for_size(over[2], px))
        self.pctUnder.setText(adj_for_size(over[3], px))
        self.pctAvg.setText(str(avg))

    def plotHistogram(self, colorhists, grayhist, px):
        global colors
        logging.debug("plotHistogram Called")
        self.plot.cla()
        self.plot.fill(grayhist, color="gray")
        for i,col in enumerate(colors):
            self.plot.plot(colorhists[i],color = col)
        self.plot.set_ylim([0,px/128])
        self.plot.set_xlim([0,256])
        self.canvas.draw()
class WidgetGallery(QDialog):
    def __init__(self, parent=None):
        super(WidgetGallery, self).__init__(parent)

        self.originalPalette = QApplication.palette()
        styleComboBox = QComboBox()
        styleComboBox.addItems(QStyleFactory.keys())

        styleLabel = QLabel("&Style:")
        styleLabel.setBuddy(styleComboBox)

        self.useStylePaletteCheckBox = QCheckBox(
            "&Use style's standard palette")
        self.useStylePaletteCheckBox.setChecked(True)

        disableWidgetsCheckBox = QCheckBox("&Disable widgets")

        self.createButtons()
        self.createButtons2()
        self.createPlotCanvas()
        self.createSpreadsheet()

        mainLayout = QGridLayout()

        mainLayout.addWidget(self.buttonGroup, 0, 0)
        mainLayout.addWidget(self.buttonGroup2, 0, 1)
        mainLayout.addWidget(self.leftGroup, 1, 1)
        mainLayout.addWidget(self.rightGroup, 1, 0)
        self.setLayout(mainLayout)

        self.setWindowTitle("jikuGUI")

    def createButtons(self):
        self.buttonGroup = QGroupBox("")
        #self.buttonGroup.setFlat(True);
        #self.buttonGroup.setStyleSheet("border:0;")
        self.buttonGroup.setGeometry(0, 0, 100, 40)
        layout = QHBoxLayout()

        self.pushButtonLoad = QtWidgets.QPushButton(self)
        self.pushButtonLoad.setText("Load Data")
        self.pushButtonLoad.clicked.connect(self.on_pushButtonLoad_clicked)
        layout.addWidget(self.pushButtonLoad)

        self.pushButtonWrite = QtWidgets.QPushButton(self)
        self.pushButtonWrite.setText("Save Data")
        self.pushButtonWrite.clicked.connect(self.on_pushButtonWrite_clicked)
        layout.addWidget(self.pushButtonWrite)

        self.pushButtonWriteAnalysis = QtWidgets.QPushButton(self)
        self.pushButtonWriteAnalysis.setText("Save Analysis")
        #self.pushButtonWrite.clicked.connect(self.on_pushButtonWrite_clicked)
        layout.addWidget(self.pushButtonWriteAnalysis)

        self.buttonGroup.setLayout(layout)

    def createButtons2(self):
        self.buttonGroup2 = QGroupBox("")
        #self.buttonGroup.setFlat(True);
        #self.buttonGroup.setStyleSheet("border:0;")
        self.buttonGroup2.setGeometry(0, 0, 100, 40)
        layout = QHBoxLayout()

        self.pushButtonPlot = QtWidgets.QPushButton(self)
        self.pushButtonPlot.setText("Plot")
        self.pushButtonPlot.clicked.connect(self.on_pushButtonPlot_clicked)

        self.pushButtonAnalysis = QtWidgets.QPushButton(self)
        self.pushButtonAnalysis.setText("Analyze")
        self.pushButtonAnalysis.clicked.connect(
            self.on_pushButtonAnalysis_clicked)

        layout.addWidget(self.pushButtonPlot)
        layout.addWidget(self.pushButtonAnalysis)

        self.buttonGroup2.setLayout(layout)

    def createSpreadsheet(self):
        self.rightGroup = QGroupBox("Data")
        self.tabs = QTabWidget()
        self.tableWidget = QTableWidget(10, 10)
        layout = QVBoxLayout()
        layout.addWidget(self.tableWidget)
        self.rightGroup.setLayout(layout)

    def createPlotCanvas(self):
        self.leftGroup = QGroupBox("Statistics")
        self.tabs = QTabWidget()

        #tab1- matplotlib
        self.tab1 = QWidget()
        self.tab1.layout = QVBoxLayout(self)

        #tab2- matplotlib
        self.tab2 = QWidget()
        self.tab2.layout = QVBoxLayout(self)

        #tab3- matplotlib
        self.tab3 = QWidget()
        self.tab3.layout = QVBoxLayout(self)

        #tab3- matplotlib
        self.tab4 = QWidget()
        self.tab4.layout = QVBoxLayout(self)

        self.tabs.addTab(self.tab1, "Plot")
        self.tabs.addTab(self.tab2, "Analysis")
        self.tabs.addTab(self.tab3, "Advanced")
        self.tabs.addTab(self.tab4, "Wizard")

        layout = QVBoxLayout()
        # a figure instance to plot on

        self.figure1 = plt.figure()
        self.ax1 = self.figure1.add_axes([0.1, 0.1, 0.8, 0.8])
        self.canvas1 = FigureCanvas(self.figure1)

        self.figure2 = plt.figure()
        self.ax2 = self.figure2.add_axes([0.1, 0.1, 0.8, 0.8])
        self.canvas2 = FigureCanvas(self.figure2)

        self.dialog = QLineEdit(self)
        self.pushButtonRun = QtWidgets.QPushButton(self)
        self.pushButtonRun.setText("run")
        self.pushButtonRun.clicked.connect(self.on_pushButtonRun_clicked)

        self.tab1.layout.addWidget(self.canvas1)

        self.tab2.layout.addWidget(self.canvas2)

        self.tab3.layout.addWidget(self.dialog)
        self.tab3.layout.addWidget(self.pushButtonRun)

        self.tab1.setLayout(self.tab1.layout)
        self.tab2.setLayout(self.tab2.layout)
        self.tab3.setLayout(self.tab3.layout)

        layout.addWidget(self.tabs)
        self.leftGroup.setLayout(layout)

    def showDialog(self):
        text, ok = QInputDialog.getText(self, 'Input Dialog', 'Enter text:')
        if ok:
            self.le.setText(str(text))

    def plot(self):
        try:
            ids = list(
                set(index.row()
                    for index in self.tableWidget.selectedIndexes()))
            print(ids)
            print(self.model[ids, :].transpose())
            self.ax1.clear()
            self.ax1.plot(self.model[ids, :].transpose())
            self.canvas1.draw()
        except:
            self.ax1.clear()

    def parser(self):
        print("OK")

    def analysis(self):
        try:
            ids = list(
                set(index.row()
                    for index in self.tableWidget.selectedIndexes()))
            print(ids)
            print(self.model[ids, :].transpose())
            t = spm1d.stats.ttest(self.model[ids, :])
            ti = t.inference(alpha=0.05, two_tailed=False, interp=True)
            self.ax2.clear()
            self.ax2.plot()
            ti.plot()
            self.canvas2.draw()
        except:
            self.ax2.clear()

    def loadCsv(self):

        fileName = QFileDialog.getOpenFileName(self, 'Open file', './',
                                               "spreadsheets (*.xlsx *.csv)")
        print(fileName)
        df = pd.read_csv(fileName[0], sep=',', header=None)
        self.model = df.values
        print(self.model)
        print(self.model.shape)
        nrows = self.model.shape[0]
        ncols = self.model.shape[1]
        if (self.tableWidget.rowCount() != nrows):
            self.tableWidget.setRowCount(nrows)
        if (self.tableWidget.columnCount() != nrows):
            self.tableWidget.setColumnCount(ncols)
        for m in range(nrows):
            for n in range(ncols):
                newitem = QtWidgets.QTableWidgetItem(str(self.model[m, n]))
                self.tableWidget.setItem(m, n, newitem)

    def writeCsv(self):
        fileName = QFileDialog.getOpenFileName(self, 'save file', 'c:\\',
                                               "Image files (*.xlsx *.csv)")
        with open(fileName[0], "w") as fileOutput:
            writer = csv.writer(fileOutput)
            for rowNumber in range(self.model.rowCount()):
                fields = [
                    self.model.data(self.model.index(rowNumber, columnNumber),
                                    QtCore.Qt.DisplayRole)
                    for columnNumber in range(self.model.columnCount())
                ]
                writer.writerow(fields)

    @QtCore.pyqtSlot()
    def on_pushButtonWrite_clicked(self):
        self.writeCsv()

    @QtCore.pyqtSlot()
    def on_pushButtonLoad_clicked(self):
        self.loadCsv()

    @QtCore.pyqtSlot()
    def on_pushButtonPlot_clicked(self):
        self.plot()

    @QtCore.pyqtSlot()
    def on_pushButtonAnalysis_clicked(self):
        self.analysis()

    @QtCore.pyqtSlot()
    def on_pushButtonRun_clicked(self):
        self.Parser()
Beispiel #17
0
class MPLCanvas(QtWidgets.QGroupBox):
    """Ultimately, this is a QWidget (as well as a FigureCanvasAgg, etc.)."""
    @enum.unique
    class WindowTypes(enum.Enum):
        Rectangular = 0
        Hann = 1
        Flattop = 2
        Tukey_5Percent = 3

    windowFunctionMap = {
        WindowTypes.Rectangular:
        lambda M: windows.boxcar(M, sym=False),
        WindowTypes.Hann:
        lambda M: windows.hann(M, sym=False),
        WindowTypes.Flattop:
        lambda M: windows.flattop(M, sym=False),
        WindowTypes.Tukey_5Percent:
        lambda M: windows.tukey(M, sym=False, alpha=0.05),
    }

    dataIsPower = False
    dataSet = None
    prevDataSet = None
    _prevAxesLabels = None
    _axesLabels = None
    _prevDataLabel = None
    _dataLabel = None

    _lastPlotTime = 0
    _isLiveData = False

    def __init__(self, parent=None):
        style_mpl()

        super().__init__(parent)

        dpi = QtWidgets.qApp.primaryScreen().logicalDotsPerInch()
        self.fig = Figure(dpi=dpi)
        self.fig.patch.set_alpha(0)

        self.axes = self.fig.add_subplot(2, 1, 1)
        self.ft_axes = self.fig.add_subplot(2, 1, 2)

        self.canvas = FigureCanvasQTAgg(self.fig)
        self.mpl_toolbar = NavigationToolbar2QT(self.canvas, self)

        self.mpl_toolbar.addSeparator()

        self.autoscaleAction = self.mpl_toolbar.addAction("Auto-scale")
        self.autoscaleAction.setCheckable(True)
        self.autoscaleAction.setChecked(True)
        self.autoscaleAction.triggered.connect(self._autoscale)

        self.mpl_toolbar.addWidget(
            QtWidgets.QLabel("Fourier transform "
                             "window: "))

        self.windowComboBox = QtWidgets.QComboBox(self.mpl_toolbar)
        for e in MPLCanvas.WindowTypes:
            self.windowComboBox.addItem(e.name, e)
        self.mpl_toolbar.addWidget(self.windowComboBox)
        self.windowComboBox.currentIndexChanged.connect(self._replot)

        vbox = QtWidgets.QVBoxLayout(self)
        vbox.addWidget(self.mpl_toolbar)
        vbox.addWidget(self.canvas)
        vbox.setContentsMargins(0, 0, 0, 0)
        vbox.setStretch(0, 1)
        vbox.setStretch(1, 1)

        self.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
                           QtWidgets.QSizePolicy.Expanding)
        self.canvas.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
                                  QtWidgets.QSizePolicy.Expanding)
        self.updateGeometry()

        self.fig.tight_layout()

        self._lines = self.axes.plot([], [], [], [], animated=True)
        self._lines[0].set_alpha(0.25)
        self._ftlines = self.ft_axes.plot([], [], [], [], animated=True)
        self._ftlines[0].set_alpha(0.25)
        self.axes.legend(['Previous', 'Current'])
        self.ft_axes.legend(['Previous', 'Current'])
        self.axes.set_title('Data')
        self.ft_axes.set_title('Fourier transformed data')
        self._redraw()

        # Use a timer with a timeout of 0 to initiate redrawing of the canvas.
        # This ensures that the eventloop has run once more and prevents
        # artifacts.
        self._redrawTimer = QtCore.QTimer(self)
        self._redrawTimer.setSingleShot(True)
        self._redrawTimer.setInterval(100)
        self._redrawTimer.timeout.connect(self._redraw)

        # will be disconnected in drawDataSet() when live data is detected.
        self._redraw_id = self.canvas.mpl_connect('draw_event',
                                                  self._redraw_artists)

    def _redraw_artists(self, *args):
        if not self._isLiveData:
            self.axes.draw_artist(self._lines[0])
            self.ft_axes.draw_artist(self._ftlines[0])

        self.axes.draw_artist(self._lines[1])
        self.ft_axes.draw_artist(self._ftlines[1])

    def _redraw(self):
        self.fig.tight_layout()
        self.canvas.draw()
        self.backgrounds = [
            self.fig.canvas.copy_from_bbox(ax.bbox)
            for ax in (self.axes, self.ft_axes)
        ]
        self._redraw_artists()

    def showEvent(self, e):
        super().showEvent(e)
        self._redrawTimer.start()

    def resizeEvent(self, e):
        super().resizeEvent(e)
        self._redrawTimer.start()

    def get_ft_data(self, data):
        delta = np.mean(np.diff(data.axes[0]))
        winFn = self.windowFunctionMap[self.windowComboBox.currentData()]
        refUnit = 1 * data.data.units
        Y = np.fft.rfft(np.array(data.data / refUnit) * winFn(len(data.data)),
                        axis=0)
        freqs = np.fft.rfftfreq(len(data.axes[0]), delta)
        dBdata = 10 * np.log10(np.abs(Y))
        if not self.dataIsPower:
            dBdata *= 2
        data_slice = np.array(freqs) < 2.1
        return (freqs[data_slice], dBdata[data_slice])

    def _dataSetToLines(self, data, line, ftline):
        if data is None:
            line.set_data([], [])
            ftline.set_data([], [])
            return

        #data.data -= np.mean(data.data)
        line.set_data(data.axes[0], data.data)
        freqs, dBdata = self.get_ft_data(data)
        ftline.set_data(freqs, dBdata)

    def _autoscale(self, *, redraw=True):
        prev_xlim = self.axes.get_xlim()
        prev_ylim = self.axes.get_ylim()
        prev_ft_xlim = self.ft_axes.get_xlim()
        prev_ft_ylim = self.ft_axes.get_ylim()

        self.axes.relim()
        self.axes.autoscale()
        self.ft_axes.relim()
        self.ft_axes.autoscale()

        need_redraw = (prev_xlim != self.axes.get_xlim()
                       or prev_ylim != self.axes.get_ylim()
                       or prev_ft_xlim != self.ft_axes.get_xlim()
                       or prev_ft_ylim != self.ft_axes.get_ylim())

        if need_redraw and redraw:
            self._redraw()

        return need_redraw

    def _replot(self,
                redraw_axes=False,
                redraw_axes_labels=False,
                redraw_data_label=False):
        if not self._isLiveData:
            self._dataSetToLines(self.prevDataSet, self._lines[0],
                                 self._ftlines[0])
        self._dataSetToLines(self.dataSet, self._lines[1], self._ftlines[1])

        if self._axesLabels and redraw_axes_labels:
            self.axes.set_xlabel('{} [{:C~}]'.format(
                self._axesLabels[0], self.dataSet.axes[0].units))
            self.ft_axes.set_xlabel('1 / {} [1 / {:C~}]'.format(
                self._axesLabels[0], self.dataSet.axes[0].units))

        if self._dataLabel and redraw_data_label:
            self.axes.set_ylabel('{} [{:C~}]'.format(self._dataLabel,
                                                     self.dataSet.data.units))

            ftUnits = self.dataSet.data.units
            if not self.dataIsPower:
                ftUnits = ftUnits**2

            self.ft_axes.set_ylabel('Power [dB-({:C~})]'.format(ftUnits))

        axis_limits_changed = False
        if (self.autoscaleAction.isChecked()):
            axis_limits_changed = self._autoscale(redraw=False)

        # check whether a full redraw is necessary or if simply redrawing
        # the data lines is enough
        if (redraw_axes or redraw_axes_labels or redraw_data_label
                or axis_limits_changed):
            self._redraw()
        else:
            for bg in self.backgrounds:
                self.canvas.restore_region(bg)
            self._redraw_artists()
            self.canvas.blit(self.axes.bbox)
            self.canvas.blit(self.ft_axes.bbox)

    def drawDataSet(self, newDataSet, axes_labels, data_label):
        plotTime = time.perf_counter()

        looksLikeLiveData = plotTime - self._lastPlotTime < 1

        if looksLikeLiveData != self._isLiveData:
            if looksLikeLiveData:
                self.canvas.mpl_disconnect(self._redraw_id)
            else:
                self._redraw_id = self.canvas.mpl_connect(
                    'draw_event', self._redraw_artists)

        self._isLiveData = looksLikeLiveData

        # artificially limit the replot rate to 5 Hz
        if (plotTime - self._lastPlotTime < 0.2):
            return

        self._lastPlotTime = plotTime

        self.prevDataSet = self.dataSet
        self.dataSet = newDataSet

        redraw_axes = (self.prevDataSet is None
                       or len(self.prevDataSet.axes) != len(self.dataSet.axes))
        if not redraw_axes:
            for x, y in zip(self.prevDataSet.axes, self.dataSet.axes):
                if x.units != y.units:
                    redraw_axes = True
                    break

        redraw_axes_labels = (
            self._axesLabels != axes_labels
            or self.prevDataSet and self.dataSet
            and self.prevDataSet.axes[0].units != self.dataSet.axes[0].units)
        redraw_data_label = (
            self._dataLabel != data_label or self.prevDataSet and self.dataSet
            and self.prevDataSet.data.units != self.dataSet.data.units)

        self._axesLabels = axes_labels
        self._dataLabel = data_label

        self._replot(redraw_axes, redraw_axes_labels, redraw_data_label)
Beispiel #18
0
class Window(QDialog):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        with open('./features_extracted.json', 'r') as file:
            self.loaded_json_data = json.load(file)

        self.figures = []
        self.canvases = []

        self.toolbars = []

        self.brainStateLabels = []
        self.accuracyLabels = []

        self.axes = []
        self.tabs = []

        self.tabs = QTabWidget()

        # a figure instance to plot on
        self.figure = plt.figure()

        # this is the Canvas Widget that displays the plot or (figure)
        self.canvas = FigureCanvas(self.figure)

        self.openFileDialog()

        # this is the Navigation Toolbar for the top of the plot
        self.toolbar = NavigationToolbar(self.canvas, self)

        # create the layout and menu
        layout = QVBoxLayout()

        menu_bar = QMenuBar()
        fileMenu = menu_bar.addMenu('File')

        importDataAction = QAction('Import Data', self)
        importDataAction.setShortcut('Ctrl+I')
        importDataAction.triggered.connect(self.openFileDialog)

        fileMenu.addAction(importDataAction)

        layout.setMenuBar(menu_bar)
        layout.addWidget(self.toolbar)

        layout.addWidget(self.canvas)

        outputHBox = QHBoxLayout()

        # create the labels that we will need to access again
        self.brainStateLabel = QLabel("Brain State : ")
        self.brainStateLabel.setFixedSize(200, 20)
        self.accuracyLabel = QLabel("Accuracy of Prediction: ")
        self.accuracyLabel.setFixedSize(400, 20)

        predictionStatisticsVBoxLeft = QVBoxLayout()
        predictionStatisticsVBoxLeft.addWidget(self.brainStateLabel)

        predictionStatisticsVBoxRight = QVBoxLayout()
        predictionStatisticsVBoxRight.addWidget(self.accuracyLabel)

        outputHBox.addLayout(predictionStatisticsVBoxLeft)
        outputHBox.addLayout(predictionStatisticsVBoxRight)

        layout.addLayout(outputHBox)
        self.setLayout(layout)

        # mouse button press event
        press_event_id = self.canvas.mpl_connect('button_press_event',
                                                 self.onclick)
        # motion_event_id = self.canvas.mpl_connect('motion_notify_event', self.on_move)

        self.plot()

        self.model = fNIRLib.load_model()

    def openFileDialog(self):
        options = QFileDialog.Options()
        # options |= QFileDialog.DontUseNativeDialog
        file_path, _ = QFileDialog.getOpenFileName(
            self,
            "QFileDialog.getOpenFileName()",
            "",
            "All Files (*);;Python Files (*.py)",
            options=options)
        if file_path:
            print(file_path)
            data = fNIRLib.importSingleton(file_path)

            data_frames = []
            for df in data:
                data_frames.append(df)

            all_features = pd.concat(data_frames)
            self.features = all_features.drop(all_features.columns[[16]],
                                              axis=1)
            self.plot()

    def onclick(self, event, i):
        print('%s click: button=%d, x=%d, y=%d, xdata=%f, ydata=%f' %
              ('double' if event.dblclick else 'single', event.button, event.x,
               event.y, event.xdata, event.ydata))
        if event.button == 1:
            self.figure.tight_layout()
            self.ax.patches.clear()

        if event.button == 3:
            self.draw_rectangle(event.xdata, i)

            x_point = int(round(event.xdata))

            ml_data = self.features.iloc[0:x_point]
            ml_data['column_id'] = ml_data.shape[0] * [0]
            ml_data['time_id'] = range(ml_data.shape[0])
            print(ml_data)

            features_extracted = feature_extraction.extract_features(
                ml_data,
                kind_to_fc_parameters=self.loaded_json_data,
                column_id="column_id",
                column_sort="time_id")

            print(features_extracted)

            predicted_class = self.model.predict_classes(
                features_extracted.values)[0][0]

            if predicted_class == 0:
                self.brainStateLabel.setText("Brain State: Low")
            else:

                self.brainStateLabel.setText("Brain State: High")
            self.accuracyLabel.setText("Prediction Accuracy: 75%")
            QApplication.processEvents()
        self.canvas.draw()

    # def on_move(self, event):
    #     # get the x and y pixel coords
    #     x, y = event.x, event.y
    #
    #     if event.inaxes:
    #         ax = event.inaxes  # the axes instance
    #         print('data coords %f %f' % (event.xdata, event.ydata))
    #     self.figure.tight_layout()

    def draw_rectangle(self, x, i):
        self.ax.patches.clear()
        rectangle = Rectangle((0, -10), width=x, height=100, color='#0F0F0F2F')
        self.ax.add_patch(rectangle)
        self.canvas.draw()

    def plot(self):
        self.figure.clear()

        # create an axis
        self.ax = self.figure.add_subplot(111)
        # self.ax.set_aspect('auto')

        self.ax.plot(self.features, '-')

        self.ax.legend(self.ax.get_lines(),
                       self.features.columns,
                       bbox_to_anchor=(0., 1.02, 1., .102),
                       loc=3,
                       ncol=8,
                       mode="expand",
                       borderaxespad=0.)
        self.ax.set_xlim(0, len(self.features))
        self.figure.tight_layout()

        # refresh canvas
        self.canvas.draw()
Beispiel #19
0
class WaterfallPlotter(QWidget):

    generated_rectangles_signal = QtCore.pyqtSignal(list) #send list of rects for data display in tree

    def __init__(self,parent):
        super(WaterfallPlotter,self).__init__(parent)

        self.get_settings()
        self.settings_update = False

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

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

        self.btn_plot = QPushButton('Default Plot')
        self.btn_plot.clicked.connect(self.default_plot)

        self.layout = QVBoxLayout()
        self.layout.addWidget(self.toolbar)
        self.layout.addWidget(self.canvas)
        self.layout.addWidget(self.btn_plot)
        self.setLayout(self.layout)
        
    
    def on_waterfall_data_signal(self,signal):
        self.waterfall_data = signal['waterfall_data'] #pandas dataframe
        self.btn_plot.setEnabled(True)

    def get_settings(self):
        try:
            with shelve.open('WaterfallSettings') as shelfFile: 
                self.keys_and_colors = shelfFile['keys_and_colors']
                shelfFile.close()
        except:
            #set and use default settings
            self.keys_and_colors = {
                                    'CR':'#03945D',
                                    'PR':'#B1EE97',
                                    'PD':'#FF6F69',
                                    'SD':'#707070'}
            with shelve.open('WaterfallSettings') as shelfFile:
                shelfFile['keys_and_colors'] = self.keys_and_colors
                shelfFile.close()

    def on_general_settings_signal(self,signal):
        self.gen_settings = signal
        self.settings_update = True
        self.default_plot()
    
    def get_bar_colors(self,responses):
        return [self.keys_and_colors[x] for x in responses]

    def default_plot(self):
        '''
        Plot waterfall data
        '''            
        self.figure.clear()
        self.rect_locations = np.arange(len(self.waterfall_data['Best response percent change']))
        self.ax = self.figure.add_subplot(111)
        self.bar_colors = self.get_bar_colors(self.waterfall_data['Overall response'])

        if self.settings_update == False:
            self.ax.tick_params(
                            axis='x',          # changes apply to the x-axis
                            which='both',      # both major and minor ticks are affected
                            bottom='on',      # ticks along the bottom edge are off
                            top='on',         # ticks along the top edge are off
                            labelbottom='on'
                            ) # labels along the bottom edge are off
            self.ax.axhline(y=20, linestyle='--', c='k', alpha=0.5, lw=2.0, label='twenty_percent')
            self.ax.axhline(y=-30, linestyle='--', c='k', alpha=0.5, lw=2.0, label='thirty_percent')
            self.ax.axhline(y=0, c='k', alpha=1, lw=2.0, label='zero_percent')
            self.ax.grid(color = 'k', axis = 'y', alpha=0.25)
            self.rects = self.ax.bar(self.rect_locations, self.waterfall_data['Best response percent change'], color=self.bar_colors)

        else:
            #settings were updated, we received them and stored in variable self.gen_settings
            self.ax.set_title(self.gen_settings[0])
            self.ax.set_xlabel(self.gen_settings[1])
            self.ax.set_ylabel(self.gen_settings[2])
            if self.gen_settings[3][0]:
                self.ax.axhline(y=20, linestyle='--', c='k', alpha=0.5, lw=2.0, label='twenty_percent')
            if self.gen_settings[3][1]:
                self.ax.axhline(y=-30, linestyle='--', c='k', alpha=0.5, lw=2.0, label='thirty_percent')
            if self.gen_settings[3][2]:
                self.ax.axhline(y=0, c='k', alpha=1, lw=2.0, label='zero_percent')

            if self.gen_settings[4][0] and ~self.gen_settings[6]:
                #show responses as labels, default color bars
                #legend depends on user specified keys
                self.rects = self.ax.bar(self.rect_locations, self.waterfall_data['Best response percent change'])
                self.add_labels(self.ax, self.rects, self.waterfall_data, 1)
            elif self.gen_settings[4][1]:
                #color bars with response type
                self.rects = self.ax.bar(self.rect_locations, self.waterfall_data['Best response percent change'], color=self.bar_colors)
                self.patches = []
                for key in self.keys_and_colors.keys():
                    self.patches.append(mpatches.Patch(color = self.keys_and_colors[key],label=key))
                self.ax.legend(handles=self.patches)
            else:
                self.rects = self.ax.bar(self.rect_locations, self.waterfall_data['Best response percent change'])
            
            if self.gen_settings[5]:
                self.plot_table()
            
            if self.gen_settings[6] and ~self.gen_settings[4][0]:
                self.add_labels(self.ax, self.rects, self.waterfall_data, 0)
            
            if ~self.gen_settings[6]

        self.ax.grid(color = 'k', axis = 'y', alpha=0.25)
        self.canvas.draw()
        self.generated_rectangles_signal.emit([self.rects])
            
    def plot_table(self):
        rows = ['%s' % x for x in self.waterfall_data.keys()]
        rows = rows[4:] #skip first three, they are the 4 standard headers, rest are table rows
        columns = self.waterfall_data['Patient number'] #patient numbers
        cell_text = []
        for row in rows:
            cell_text_temp = []
            for col in range(len(columns)):
                cell_text_temp.append(self.waterfall_data[row][col])
            cell_text.append(cell_text_temp)
        the_table = self.ax.table(cellText=cell_text, rowLabels=rows, colLabels=columns, loc='bottom', cellLoc='center', colLoc='center')
        plt.subplots_adjust(bottom=0.15,left=0.5)
        self.ax.set_xlim(-0.5,len(columns)-0.5)
        self.ax.tick_params(
                        axis='x',          # changes apply to the x-axis
                        which='both',      # both major and minor ticks are affected
                        bottom='off',      # ticks along the bottom edge are off
                        top='off',         # ticks along the top edge are off
                        labelbottom='off'
                        ) # labels along the bottom edge are off
    
    def update_plot(self):
        '''
        TODO
        '''
        pass
                    
    def add_labels(self, ax, rects, waterfall_data, label_type):
        '''
        Add labels above/below bars. label_type == 1 --> display responses; == 0 --> display cancer type
        '''
        i = 0
        if label_type:
            for rect in rects:
                height = rect.get_height()
                if height >= 0:
                    valign = 'bottom'
                else:
                    valign = 'top'
                    
                ax.text(rect.get_x() + rect.get_width()/2., height,
                        '%s' % waterfall_data['Overall response'][i], ha='center', va=valign)
                i+=1
        else:
            for rect in rects:
                height = rect.get_height()
                if height >= 0:
                    valign = 'top'
                    hgt = -1
                else:
                    valign = 'bottom'
                    hgt = 1

                ax.text(rect.get_x() + rect.get_width()/2., hgt,
                        '%s' % waterfall_data['Cancer'][i], ha='center', va=valign, rotation='vertical')
                i+=1   
Beispiel #20
0
class OpappPlotLayout(QVBoxLayout):
    def __init__(self):

        super(OpappPlotLayout, self).__init__()

        self.start = 0
        self.end = 1
        self.filter = 1
        self.pos_x = 0
        self.pos_y = 0
        self.vmin = -1
        self.vmax = 1
        self.obj = None

        self.edit_start = QLineEdit()
        self.edit_start.setText(str(self.start))
        self.edit_start.textChanged.connect(self.draw)

        self.edit_end = QLineEdit()
        self.edit_end.setText(str(self.end))
        self.edit_end.textChanged.connect(self.draw)

        self.edit_filter = QLineEdit()
        self.edit_filter.setText(str(self.filter))
        self.edit_filter.textChanged.connect(self.draw)

        self.edit_pos_x = QLineEdit()
        self.edit_pos_x.setText(str(self.pos_x))
        self.edit_pos_x.textChanged.connect(self.draw)

        self.edit_pos_y = QLineEdit()
        self.edit_pos_y.setText(str(self.pos_y))
        self.edit_pos_y.textChanged.connect(self.draw)

        layout = QHBoxLayout()
        layout.addWidget(QLabel(u'start'))
        layout.addWidget(self.edit_start)
        layout.addWidget(QLabel(u'end'))
        layout.addWidget(self.edit_end)
        layout.addWidget(QLabel(u'filter'))
        layout.addWidget(self.edit_filter)
        layout.addWidget(QLabel(u'pos_x'))
        layout.addWidget(self.edit_pos_x)
        layout.addWidget(QLabel(u'pos_y'))
        layout.addWidget(self.edit_pos_y)
        self.addLayout(layout)

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

        self.addWidget(self.canvas)

        try:
            self.loadPath()
        except:
            pass

    def setObject(self, obj):
        self.obj = obj
        self.vmax = obj.vmax
        self.vmin = obj.vmin
        if obj is None: return
        if len(self.obj.data) > 0:
            L, H, W = obj.data.shape
            self.edit_pos_y.setText(str(H // 2))
            self.edit_pos_x.setText(str(H // 2))
            self.edit_start.setText(str(0))
            self.edit_end.setText(str(L))
            #self.plot.set_data(t, ts)
            #self.plot, = self.axes.plot([], [])
            self.draw()

    def calc_APD70(self, ts):
        apd_start = 0
        apd_end = 0
        threshold = 0.7 * ts.min() + 0.3 * ts.max()
        flg = 0
        for i, v in enumerate(ts):
            if i == 0: continue
            if v > threshold and flg == 0:
                flg = 1
                apd_start = i
            if v <= threshold and flg == 1:
                flg = 2
                apd_end = i
        return threshold, apd_start, apd_end

    def draw(self):
        self.axes.clear()
        self.start = int(self.edit_start.text())
        self.end = int(self.edit_end.text())
        self.filter = int(self.edit_filter.text())
        self.pos_x = int(self.edit_pos_x.text())
        self.pos_y = int(self.edit_pos_y.text())
        #try:
        ts = xp.asnumpy(self.obj.data[self.start:self.end, self.pos_y,
                                      self.pos_x])
        t = np.arange(self.start, self.end)
        if self.filter > 1:
            ts = gaussian_filter1d(
                ts,
                sigma=self.filter,
            )

        self.axes.set_xlim(self.start, self.end)
        #self.axes.set_ylim(self.vmin, self.vmax)
        self.axes.set_ylim(ts.min(), ts.max())
        #self.plot.set_data(t, ts)
        self.plot = self.axes.plot(t, ts)

        threshold, apd_start, apd_end = self.calc_APD70(ts)
        self.axes.hlines(threshold,
                         self.start + apd_start,
                         self.start + apd_end,
                         "blue",
                         linestyles="dashed")
        self.axes.text(self.start + (0.7 * apd_start + 0.3 * apd_end),
                       threshold + (ts.max() - ts.min()) * 0.1,
                       "APD70: %s (ms)" % (apd_end - apd_start),
                       fontsize=20)

        self.canvas.draw()

        pass
class WaterfallPlotter(QWidget):

    generated_rectangles_signal = QtCore.pyqtSignal(list) #send list of rects for data display in tree

    def __init__(self,parent):
        super(WaterfallPlotter,self).__init__(parent)

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

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

        self.btn_plot = QPushButton('Default Plot')
        self.btn_plot.clicked.connect(self.default_plot)

        self.layout = QVBoxLayout()
        self.layout.addWidget(self.toolbar)
        self.layout.addWidget(self.canvas)
        self.layout.addWidget(self.btn_plot)
        self.setLayout(self.layout)
    
    def on_waterfall_data_signal(self,signal):
        self.waterfall_data = signal['waterfall_data'] #pandas dataframe
        self.btn_plot.setEnabled(True)

    def on_general_settings_signal(self,signal):
        try:
            hasattr(self,'ax')
            self.ax.set_title(signal[0])
            self.ax.set_xlabel(signal[1])
            self.ax.set_ylabel(signal[2])
            self.canvas.draw()
        except Exception as e:
            print(e)
            
    def default_plot(self):
        '''
        Plot waterfall data
        '''
        self.figure.clear()
        self.rect_locations = np.arange(len(self.waterfall_data['Best response percent change']))
        self.ax = self.figure.add_subplot(111)
        self.ax.axhline(y=20, linestyle='--', c='k', alpha=0.5, lw=2.0, label='twenty_percent')
        self.ax.axhline(y=-30, linestyle='--', c='k', alpha=0.5, lw=2.0, label='thirty_percent')
        self.ax.axhline(y=0, c='k', alpha=1, lw=2.0, label='zero_percent')
        self.ax.grid(color = 'k', axis = 'y', alpha=0.25)
        self.rects = self.ax.bar(self.rect_locations,self.waterfall_data['Best response percent change'])
        self.auto_label_responses(self.ax, self.rects, self.waterfall_data)
        #self.plot_table()
        self.canvas.draw()
        self.ax.hold(False) #rewrite the plot when plot() called
        self.generated_rectangles_signal.emit([self.rects])
            
    def plot_table(self):
        rows = ['%s' % x for x in self.waterfall_data.keys()]
        rows = rows[4:] #skip first three, they are the 4 standard headers, rest are table rows
        columns = self.waterfall_data['Patient number'] #patient numbers
        cell_text = []
        for row in rows:
            cell_text_temp = []
            for col in range(len(columns)):
                cell_text_temp.append(self.waterfall_data[row][col])
            cell_text.append(cell_text_temp)
        the_table = plt.table(cellText=cell_text, rowLabels=rows, colLabels=columns, loc='bottom', cellLoc='center')
        plt.subplots_adjust(bottom=0.15,left=0.5)
        self.ax.set_xlim(-0.5,len(columns)-0.5)
        plt.tick_params(
                        axis='x',          # changes apply to the x-axis
                        which='both',      # both major and minor ticks are affected
                        bottom='off',      # ticks along the bottom edge are off
                        top='off',         # ticks along the top edge are off
                        labelbottom='off'
                        ) # labels along the bottom edge are off
    
    def update_plot(self):
        '''
        TODO
        '''
        pass
                    
    def auto_label_responses(self, ax, rects, waterfall_data):
        '''Add labels above/below bars'''
        i = 0
        for rect in rects:
            height = rect.get_height()
            if height >= 0:
                valign = 'bottom'
            else:
                valign = 'top'
                
            ax.text(rect.get_x() + rect.get_width()/2., height,
                    '%s' % waterfall_data['Overall response'][i], ha='center', va=valign)
            i+=1
Beispiel #22
0
class optMonitor(_optMonitor, _optMonitorUI):
    setStatusBar = QtCore.Signal(str)
    updateGraph = QtCore.Signal()

    def __init__(self, dat, parent=None):
        '''
            Constructor for model set up dialog
        '''
        super(optMonitor, self).__init__(parent=parent)
        self.settingsForm = parent
        self.setupUi(self)  # Create the widgets
        self.dat = dat  # all of the session data

        self.msgSubwindow = optMessageWindow(self)
        self.plotSubwindow = noCloseWidget(self)
        self.plotSubwindow.setLayout(QVBoxLayout())
        self.coordPlotSubwindow = noCloseWidget(self)
        self.coordPlotSubwindow.setLayout(QVBoxLayout())

        self.plotSubwindow.setMaximumSize(5000, 3000)
        self.coordPlotSubwindow.setMaximumSize(5000, 3000)

        self.mdiArea.addSubWindow(self.plotSubwindow)
        self.plotSubwindow.setWindowTitle("Objective Function Plot")
        self.mdiArea.addSubWindow(self.coordPlotSubwindow)
        self.coordPlotSubwindow.setWindowTitle(
            "Best Solution Parallel Coordinate Plot")
        self.mdiArea.addSubWindow(self.msgSubwindow)
        self.msgSubwindow.setWindowTitle("Optimization Solver Messages")

        self.startButton.clicked.connect(self.startOptimization)
        self.stopButton.clicked.connect(self.stopOptimization)
        self.msgSubwindow.clearMsgButton.clicked.connect(self.clearMessages)

        # setup plot the plots
        self.objFig = Figure(figsize=(600, 600),
                             dpi=72,
                             facecolor=(1, 1, 1),
                             edgecolor=(0, 0, 0),
                             tight_layout=True)
        self.coordFig = Figure(figsize=(600, 600),
                               dpi=72,
                               facecolor=(1, 1, 1),
                               edgecolor=(0, 0, 0),
                               tight_layout=True)
        self.objFigAx = self.objFig.add_subplot(111)
        self.coordFigAx = self.coordFig.add_subplot(111)
        self.objCanvas = FigureCanvas(self.objFig)
        self.coordCanvas = FigureCanvas(self.coordFig)
        self.plotSubwindow.layout().addWidget(self.objCanvas)
        self.objCanvas.setParent(self.plotSubwindow)
        self.coordPlotSubwindow.layout().addWidget(self.coordCanvas)
        self.coordCanvas.setParent(self.coordPlotSubwindow)
        self.timer = QtCore.QTimer(self)
        #self.connect(
        #    self.timer,
        #    QtCore.SIGNAL("timeout()"),
        #    self.updateStatus)
        self.timer.timeout.connect(self.updateStatus)
        self.updateDelay = 500
        self.delayEdit.setText(str(self.updateDelay))
        self.delayEdit.textChanged.connect(self.updateDelayChange)
        self.opt = None
        self.bestObj = 0
        self.bestCoord = None
        self.iteration = 0
        self.mdiArea.tileSubWindows()
        self.startButton.setEnabled(True)
        self.stopButton.setEnabled(False)

    def createMessageWindow(self):
        pass

    def createParallelAxisPlot(self):
        pass

    def createObjectivePlot(self):
        pass

    def updateDelayChange(self):
        if self.delayEdit.text() == "":
            self.updateDelay = 0
        else:
            try:
                self.updateDelay = int(float(self.delayEdit.text()))
            except:
                self.delayEdit.setText(str(self.updateDelay))

    def clearMessages(self):
        self.msgSubwindow.clearMessages()
        self.msgSubwindow.statusLine.setText("")

    def clearPlots(self):
        self.objFigAx.clear()
        self.coordFigAx.clear()
        self.objFigAx.set_xlabel("Iteration")
        self.objFigAx.set_ylabel("Objective")
        #self.objCanvas.draw()
        #self.coordCanvas.draw()

    def coordAxSetup(self):
        self.coordFigAx.clear()
        self.xnames = []
        gr = self.dat.flowsheet
        for name in self.opt.prob.v:
            self.xnames.append(name)
        self.coordFigAx.set_xlabel("Variable")
        self.coordFigAx.set_ylabel("Scaled Value")
        self.coordFigAx.set_ylim(-0.1, 10.1, auto=False)
        self.coordFigAx.set_xlim(0.75, len(self.xnames) + 0.25, auto=False)
        self.coordFigAx.set_yticks(list(range(11)))
        self.coordFigAx.set_xticks(list(range(1, len(self.xnames) + 1)))
        self.coordFigAx.set_xticklabels(self.xnames, rotation='vertical')
        self.bestX = [11] * len(self.xnames)
        self.sampLim = [[11] * len(self.xnames), [11] * len(self.xnames)]
        self.coordXCoord = list(range(1, (len(self.bestX) + 1)))
        self.coorFigLine1 = self.coordFigAx.plot(self.coordXCoord, self.bestX)
        self.coorFigLine2 = self.coordFigAx.plot(self.coordXCoord,
                                                 self.sampLim[0], 'bo')
        self.coorFigLine3 = self.coordFigAx.plot(self.coordXCoord,
                                                 self.sampLim[1], 'bo')

    def startOptimization(self):
        self.dat.flowsheet.generateGlobalVariables()
        pg = self.dat.optSolvers.plugins[self.dat.optProblem.solver].\
            opt(self.dat)
        e = self.dat.optProblem.check(self.dat.flowsheet, pg.minVars,
                                      pg.maxVars)
        if not e[0] == 0:
            QMessageBox.information(
                self, "Error",
                "The optimization will not be started there is an error in the set up:\n"
                + e[1])
            return
        self.dat.save("backupBeforeOpt.json", False)
        self.clearPlots()
        self.objCanvas.draw()
        self.settingsForm.running = True
        self.opt = self.dat.optProblem.run(self.dat)
        time.sleep(
            0.5)  #give the optimization function a little time to get started
        self.coordAxSetup()
        self.a = True
        self.timer.start(self.updateDelay)
        self.timeRunning = time.time()
        self.startButton.setEnabled(False)
        self.stopButton.setEnabled(True)
        self.setStatusBar.emit("Optimization Running")

    def stopOptimization(self):
        self.opt.terminate()

    def updateStatus(self):
        done = False
        if self.opt.updateGraph:
            self.opt.updateGraph = False
            self.updateGraph.emit()
        if not self.opt.isAlive(): done = True
        while not self.opt.msgQueue.empty():
            msg = str(self.opt.msgQueue.get(False))
            self.msgSubwindow.msgTextBrowser.append(msg)
        bestChange = False
        itChange = False
        updateStatusLine = False
        objPoints = [[], []]
        while not self.opt.resQueue.empty():
            msg = self.opt.resQueue.get(False)
            if msg[0] == "BEST":
                self.bestObj = msg[1][0]
                self.bestX = msg[2]
                bestChange = True
            elif msg[0] == "SAMP":
                if self.a:
                    self.samp = np.array(msg[1])
                    self.sampLim = [[0] * len(self.xnames),
                                    [10] * len(self.xnames)]
                    for i in range(len(self.xnames)):
                        self.sampLim[0][i] = np.min(self.samp[:, i])
                        self.sampLim[1][i] = np.max(self.samp[:, i])
                    bestChange = True
            elif msg[0] == "IT":
                self.iteration = msg[1]
                itChange = True
                objPoints[0].append(msg[1])
                objPoints[1].append(msg[2])
            elif msg[0] == "PROG":
                itJobsComplete = msg[1]
                itTotalJobs = msg[2]
                itErrors = msg[3]
                it = msg[4]
                totalRead = msg[5]
                totalErrors = msg[6]
                updateStatusLine = True
        if bestChange:
            self.coorFigLine1[0].set_data(self.coordXCoord, self.bestX)
            self.coorFigLine2[0].set_data(self.coordXCoord, self.sampLim[0])
            self.coorFigLine3[0].set_data(self.coordXCoord, self.sampLim[1])
            self.coordCanvas.draw()
        if itChange:
            self.objFigAx.plot(objPoints[0], objPoints[1], 'bo')
            self.objCanvas.draw()
        if updateStatusLine:
            self.msgSubwindow.statusLine.setText("".join([
                "ITERATION ",
                str(it), ": ",
                str(itJobsComplete), "/",
                str(itTotalJobs), "  Err: ",
                str(itErrors), " TOTAL Complete: ",
                str(totalRead), " Err:",
                str(totalErrors)
            ]))
        if done:
            self.timer.stop()
            self.startButton.setEnabled(True)
            self.stopButton.setEnabled(False)
            self.setStatusBar.emit(
                "Optimization Finished, Elapsed Time: " +
                hhmmss(math.floor(time.time() - self.timeRunning)))
            self.settingsForm.refreshContents()
            self.settingsForm.running = False
        else:
            self.setStatusBar.emit(
                "Optimization Running, Elapsed Time: " +
                hhmmss(math.floor(time.time() - self.timeRunning)))
Beispiel #23
0
class MinionCwodmrUI(QWidget):
    continueodmr = pyqtSignal()
    def __init__(self, parent):
        super(MinionCwodmrUI, self).__init__(parent)
        self.parent = parent
        self.counter = self.parent.counter

        # smiq.connect(smiq)
        self.measurementrunning = False

        self.frequency = 2.87*10**9  #Hz
        self.power = -20.
        self.modi = ['const', 'list']
        self.mode = 'const'
        self.cwodmrdata = np.zeros(100)
        self.freqlist = []
        self.powerlist = []

        self.uisetup()

    def __del__(self):
        pass# smiq.disconnect(smiq)

    def uisetup(self):
        self.cwodmrfigure = Figure()
        self.cwodmrcanvas = FigureCanvas(self.cwodmrfigure)
        self.cwodmrcanvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.cwodmrcanvas.setMinimumSize(50, 50)
        self.cwodmrtoolbar = NavigationToolbar(self.cwodmrcanvas, self)
        self.cwodmraxes = self.cwodmrfigure.add_subplot(111)
        self.cwodmraxes.hold(False)

        self.freqlabel = QLabel('Frequency [GHz]')
        self.freqtext = QDoubleSpinBox()
        self.freqtext.setRange(0, 6)
        self.freqtext.setDecimals(6)
        self.freqtext.setSingleStep(0.001)
        self.freqtext.setValue(self.frequency/(1.*10**9))
        self.freqtext.editingFinished.connect(self.freqchanged)

        self.powerlabel = QLabel('Power [dBm]')
        self.powertext = QDoubleSpinBox()
        self.powertext.setRange(-140, 16)
        self.powertext.setDecimals(1)
        self.powertext.setValue(self.power)
        self.powertext.editingFinished.connect(self.powerchanged)

        self.modeselectlabel = QLabel('mode:')
        self.modeselect = QComboBox()
        self.modeselect.addItems(self.modi)
        self.modeselect.currentIndexChanged.connect(self.modechange)

        self.toggleoutputbutton = QPushButton('output on/off')
        self.toggleoutputbutton.setCheckable(True)
        self.toggleoutputbutton.setStyleSheet("QPushButton {background-color: red;}")
        self.toggleoutputbutton.toggled.connect(self.toggleoutput)

        self.listtable = QTableWidget()
        self.listtable.setColumnCount(4)
        self.listtable.setRowCount(1)
        self.listtable.setHorizontalHeaderLabels(('start[GHz]', 'stop[GHz]', 'points[#]', 'power[dBm]'))

        self.listtableaddrowbutton = QPushButton('add row')
        self.listtableaddrowbutton.clicked.connect(self.listtableaddrow)
        self.listtableremoverowbutton = QPushButton('remove row')
        self.listtableremoverowbutton.clicked.connect(self.listtableremoverow)


        self.sendlisttosmiqbutton = QPushButton('send list')
        self.sendlisttosmiqbutton.clicked.connect(self.sendlisttosmiq)

        self.startcwodmrbutton = QPushButton('start sweep')
        self.startcwodmrbutton.setCheckable(True)
        self.startcwodmrbutton.setStyleSheet("QPushButton {background-color: red;}")
        self.startcwodmrbutton.toggled.connect(self.startcwodmr)

        self.abortodmrsweepbutton = QPushButton('abort sweep')
        self.abortodmrsweepbutton.clicked.connect(self.abortodmrsweep)

        self.saveodmrsweepbutton = QPushButton('save spectrum')
        self.saveodmrsweepbutton.clicked.connect(self.saveodmrsweep)

        # LAYOUT

        cwodmrlayout = QGridLayout()
        cwodmrlayout.addWidget(self.cwodmrcanvas)
        cwodmrlayout.addWidget(self.cwodmrtoolbar)
        cwodmrlayout.addWidget(self.freqlabel)
        cwodmrlayout.addWidget(self.freqtext)
        cwodmrlayout.addWidget(self.powerlabel)
        cwodmrlayout.addWidget(self.powertext)
        cwodmrlayout.addWidget(self.modeselectlabel)
        cwodmrlayout.addWidget(self.modeselect)
        cwodmrlayout.addWidget(self.toggleoutputbutton)
        cwodmrlayout.addWidget(self.listtable)
        cwodmrlayout.addWidget(self.listtableaddrowbutton)
        cwodmrlayout.addWidget(self.listtableremoverowbutton)
        cwodmrlayout.addWidget(self.sendlisttosmiqbutton)
        cwodmrlayout.addWidget(self.startcwodmrbutton)
        cwodmrlayout.addWidget(self.abortodmrsweepbutton)
        cwodmrlayout.addWidget(self.saveodmrsweepbutton)

        self.setLayout(cwodmrlayout)


    def abortodmrsweep(self):
        try:
            print('aborting sweep')
            self.cwODMRaquisition.stop()
            self.cwODMRaquisitionthread.quit()
        except:
            print('no sweep running')

    def saveodmrsweep(self):
        np.save('odmr_data.npy', self.cwodmrdata)
        print('spectrum saved')

    def freqchanged(self):
        freq = self.freqtext.value()*10**9
        self.freq = smiq.freq(smiq, freq)

    def powerchanged(self):
        power = self.powertext.value()
        self.power = smiq.power(smiq, power)

    def modechange(self):
        pass

    def toggleoutput(self):
        if self.toggleoutputbutton.isChecked() is True:
            self.toggleoutputbutton.setStyleSheet("QPushButton {background-color: green;}")
            smiq.on(smiq)
        else:
            self.toggleoutputbutton.setStyleSheet("QPushButton {background-color: red;}")
            smiq.off(smiq)

    def listtableaddrow(self):
        self.listtable.insertRow(self.listtable.rowCount()+1)
        self.listtable.setRowCount(self.listtable.rowCount()+1)


    def listtableremoverow(self):
        if self.listtable.rowCount() >= 2:
            self.listtable.removeRow(self.listtable.rowCount())
            self.listtable.setRowCount(self.listtable.rowCount()-1)
        else:
            pass

    def sendlisttosmiq(self):
        self.freqlist = []
        self.powerlist = []
        self.listdata = np.zeros((self.listtable.rowCount(), self.listtable.columnCount()))
        for i in range(self.listtable.rowCount()):
            for j in range(self.listtable.columnCount()):
                self.listdata[i, j] = float(self.listtable.item(i, j).text().replace(',', '.'))
        for i in range(len(self.listdata)):
            list = self.listdata[i, :]
            self.freqlist.extend(np.array(np.linspace(list[0]*10**9, list[1]*10**9, int(list[2]))))
            self.powerlist.extend(np.ones(int(list[2]))*list[3])
        self.power = self.powerlist[0]
        print('list updated')
        # smiq.setlist(smiq, self.freqlist, self.powerlist)

    @pyqtSlot(np.ndarray)
    def updateODMRdata(self, odmrupdate):
        self.cwodmrdataplot += odmrupdate
        if np.size(self.cwodmrdata, 0) == 1:
            self.cwodmrdata = odmrupdate
            self.cwodmraxes.plot(self.freqlist[:-1], self.cwodmrdataplot[:-1])
        else:
            self.cwodmrdata = np.vstack((self.cwodmrdata, odmrupdate))
            self.cwodmraxes.plot(self.freqlist[:-1], self.cwodmrdataplot[:-1])

        # self.cwodmraxes.relim()
        # self.cwodmraxes.autoscale_view()
        self.cwodmrcanvas.draw()



    @pyqtSlot()
    def continueodmraquisition(self):
        self.continueodmr.emit()

    def startcwodmr(self):
        if self.startcwodmrbutton.isChecked() is True:
            if self.parent.hardware_stage is True and self.parent.hardware_counter is True:
                self.measurementrunning = True
                self.cwodmrdata = np.zeros(len(self.freqlist))
                self.cwodmrdataplot = np.zeros(len(self.freqlist))
                self.cwODMRaquisition = MinionODMRAquisition(self.parent.fpga, self.parent.confocalwidget.xpos, self.parent.confocalwidget.ypos, self.parent.confocalwidget.zpos, self.power, self.freqlist)
                self.cwODMRaquisitionthread = QThread(self, objectName='workerThread')
                self.cwODMRaquisition.moveToThread(self.cwODMRaquisitionthread)
                self.cwODMRaquisition.finished.connect(self.cwODMRaquisitionthread.quit)
                self.cwODMRaquisition.track.connect(self.parent.trackerwidget.findmaxclicked)
                self.cwODMRaquisition.update.connect(self.updateODMRdata)
                self.continueodmr.connect(self.cwODMRaquisition.trackfinished)
                self.cwODMRaquisitionthread.started.connect(self.cwODMRaquisition.longrun)
                self.cwODMRaquisitionthread.finished.connect(self.cwODMRaquisitionthread.deleteLater)
                # self.findmax.update.connect(self.updatefindcentermaps)

                self.cwODMRaquisitionthread.start()

            self.startcwodmrbutton.setStyleSheet("QPushButton {background-color: green;}")



            # self.parent.fpga.settriggermasks(mask=8, invertedmask=8)  # SetTriggerMask + SetTriggerinvertedMask
            # self.parent.fpga.setnumbercountingbins(len(self.freqlist))  # SetNumberOfTriggeredCountingBins
            # print('num bins:', self.parent.fpga.getnumbercountingbins())
            #
            # self.parent.fpga.setcountingbinrepetitions(1)  # SetTriggeredCountingBinRepetitions
            # self.parent.fpga.setsplittriggeredbins(0)  # SetSplitTriggeredCountingBins
            # smiq.liston(smiq)
            # time.sleep(2)
            # self.parent.fpga.resettriggerbins()  #ResetTriggeredCountingData
            # time.sleep(0.001)
            # self.parent.fpga.enabletriggeredcounting()  #EnableTriggeredCounting
            # time.sleep(0.001)
            # self.cwodmrdata = np.zeros(len(self.freqlist))
            # # for i in range(2):
            # smiq.listrun(smiq)
            # time.sleep(len(self.freqlist)*0.011*2)
            # print('binpos:', self.parent.fpga.getcurrentbinpos())
            # print('counttime:', self.parent.fpga.checkcounttime())
            # smiq.listrun(smiq)
            # apd1, apd2, apd_sum = self.parent.fpga.readcountingbins()
            # self.cwodmrdata += apd_sum
            # print(self.cwodmrdata)
            # # time.sleep(0.5)
            # # smiq.cw(smiq, 2.87*10**9, -20)
            # # disable triggered counting
            #
            # # self.counter.write(b'r')  #DisableTriggeredCounting
            # # self.counter.write(b'0')  #ResetTriggeredCountingData
            #
            # check_counttime = self.parent.fpga.checkcounttime()  # check counttime
            # print('counttime:', check_counttime)
            #
            # self.counter.write(b'r')  #DisableTriggeredCounting

            # TODO - remove below and fix above
            # dont use list mode and sweep over cw modes


        else:
            self.startcwodmrbutton.toggle()
            self.startcwodmrbutton.setStyleSheet("QPushButton {background-color: red;}")
Beispiel #24
0
class R2DWindow(QtWidgets.QMainWindow):

    XY_VIEW = "X/Y"
    THREE_PANEL_VIEW = "Three panel"

    def __init__(self):
        super(R2DWindow, self).__init__()
        self.fixed_img = None
        self.moving_img = None

        self.setGeometry(0, 0, 1024, 768)
        #
        # Menus
        #
        self.file_menu = QtWidgets.QMenu("&File", self)
        self.file_menu.addAction("Open Fixed", self.open_fixed)
        self.file_menu.addAction("Open Moving", self.open_moving)
        self.file_menu.addAction("Save", self.save)
        self.menuBar().addMenu(self.file_menu)
        #
        # Splitter
        #
        main_widget = QtWidgets.QWidget()
        self.setCentralWidget(main_widget)
        top_layout = QtWidgets.QVBoxLayout()
        main_widget.setLayout(top_layout)
        splitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
        top_layout.addWidget(splitter)
        #
        # Controls
        #
        left_widget = QtWidgets.QWidget()
        splitter.addWidget(left_widget)
        left_layout = QtWidgets.QVBoxLayout()
        left_widget.setLayout(left_layout)
        # offset
        group = QtWidgets.QGroupBox("Offset")
        left_layout.addWidget(group)
        group_layout = QtWidgets.QVBoxLayout()
        group.setLayout(group_layout)

        hlayout = QtWidgets.QHBoxLayout()
        group_layout.addLayout(hlayout)
        hlayout.addWidget(QtWidgets.QLabel("X:"))
        self.w_off_x = QtWidgets.QSpinBox()
        hlayout.addWidget(self.w_off_x)

        hlayout = QtWidgets.QHBoxLayout()
        group_layout.addLayout(hlayout)
        hlayout.addWidget(QtWidgets.QLabel("Y:"))
        self.w_off_y = QtWidgets.QSpinBox()
        hlayout.addWidget(self.w_off_y)
        # center
        group = QtWidgets.QGroupBox("Center")
        left_layout.addWidget(group)
        group_layout = QtWidgets.QVBoxLayout()
        group.setLayout(group_layout)

        hlayout = QtWidgets.QHBoxLayout()
        group_layout.addLayout(hlayout)
        hlayout.addWidget(QtWidgets.QLabel("X:"))
        self.w_center_x = QtWidgets.QSpinBox()
        hlayout.addWidget(self.w_center_x)

        hlayout = QtWidgets.QHBoxLayout()
        group_layout.addLayout(hlayout)
        hlayout.addWidget(QtWidgets.QLabel("Y:"))
        self.w_center_y = QtWidgets.QSpinBox()
        hlayout.addWidget(self.w_center_y)

        self.w_center_button = QtWidgets.QPushButton("Center")
        group_layout.addWidget(self.w_center_button)
        self.w_center_button.clicked.connect(self.on_center)
        # angle
        group = QtWidgets.QGroupBox("Rotation")
        left_layout.addWidget(group)
        group_layout = QtWidgets.QVBoxLayout()
        group.setLayout(group_layout)
        hlayout = QtWidgets.QHBoxLayout()
        group_layout.addLayout(hlayout)
        hlayout.addWidget(QtWidgets.QLabel("Angle in degrees:"))
        self.w_angle = QtWidgets.QDoubleSpinBox()
        hlayout.addWidget(self.w_angle)
        hlayout = QtWidgets.QHBoxLayout()
        group_layout.addLayout(hlayout)
        self.w_flip_lr = QtWidgets.QCheckBox("Flip left/right")
        hlayout.addWidget(self.w_flip_lr)
        hlayout = QtWidgets.QHBoxLayout()
        group_layout.addLayout(hlayout)
        self.w_flip_ud = QtWidgets.QCheckBox("Flip up/down")
        hlayout.addWidget(self.w_flip_ud)
        # z heights
        group = QtWidgets.QGroupBox("Z height and downsample")
        left_layout.addWidget(group)
        group_layout = QtWidgets.QVBoxLayout()
        group.setLayout(group_layout)
        hlayout = QtWidgets.QHBoxLayout()
        group_layout.addLayout(hlayout)
        hlayout.addWidget(QtWidgets.QLabel("Fixed:"))
        self.fixed_img_z = QtWidgets.QSpinBox()
        hlayout.addWidget(self.fixed_img_z)
        hlayout = QtWidgets.QHBoxLayout()
        group_layout.addLayout(hlayout)
        hlayout.addWidget(QtWidgets.QLabel("Moving:"))
        self.moving_img_z = QtWidgets.QSpinBox()
        hlayout.addWidget(self.moving_img_z)
        hlayout = QtWidgets.QHBoxLayout()
        group_layout.addLayout(hlayout)
        hlayout.addWidget(QtWidgets.QLabel("Downsample: "))
        self.w_downsample = QtWidgets.QSpinBox()
        hlayout.addWidget(self.w_downsample)
        self.w_downsample.setMinimum(1)
        self.w_downsample.setMaximum(32)
        self.w_downsample.setValue(1)
        hlayout = QtWidgets.QHBoxLayout()
        group_layout.addLayout(hlayout)
        hlayout.addWidget(QtWidgets.QLabel("View"))
        self.w_view_choice = QtWidgets.QComboBox()
        self.w_view_choice.addItems([self.XY_VIEW, self.THREE_PANEL_VIEW])
        self.w_view_choice.setCurrentIndex(1)
        self.w_view_choice.setEditable(False)
        hlayout.addWidget(self.w_view_choice)

        self.show_button = QtWidgets.QPushButton("Show")
        left_layout.addWidget(self.show_button)
        self.show_button.setDisabled(True)
        self.show_button.clicked.connect(self.on_show)

        left_layout.addStretch(1)
        #
        # Matplotlib canvas
        #
        self.figure = Figure()
        self.canvas = FigureCanvasQTAgg(self.figure)
        splitter.addWidget(self.canvas)
        self.addToolBar(NavigationToolbar(self.canvas, self))
        self.figure.add_subplot(1, 1, 1)
        self.canvas.draw()

    def open_fixed(self):
        try:
            self.fixed_img = self.open_any("Fixed")
        except UserWarning:
            return
        except FileNotFoundError as e:
            QtWidgets.QMessageBox.warning(self, "File not found", e.strerror)
            return
        self.fixed_img_z.setMinimum(0)
        self.fixed_img_z.setMaximum(self.fixed_img.shape[2])
        self.w_center_x.setMaximum(self.fixed_img.shape[0])
        self.w_center_y.setMaximum(self.fixed_img.shape[1])
        self.update_ui()

    def open_any(self, name):
        # Grrr... native directory dialogs are BROKEN in Gnome, it seems.
        # So use the generic built-in
        #
        filename = QtWidgets.QFileDialog.getExistingDirectory(
            self,
            "%s ZARR file name" % name,
            ".",
            QtWidgets.QFileDialog.ShowDirsOnly | QtWidgets.QFileDialog.DontUseNativeDialog
        )
        if len(filename) == 0:
            raise UserWarning("No filename entered")
        try:
            return zarr.open(filename, mode="r")
        except:
            raise FileNotFoundError(errno.ENOENT,
                                    "Unable to open %s as ZARR file" % filename,
                                    filename)

    def open_moving(self):
        try:
            self.moving_img = self.open_any("Moving")
        except UserWarning:
            return
        except FileNotFoundError as e:
            QtWidgets.QMessageBox.warning(self, "File not found", e.strerror())
            return
        self.w_off_x.setMinimum(-self.moving_img.shape[0])
        self.w_off_x.setMaximum(self.moving_img.shape[0])
        self.w_off_y.setMinimum(-self.moving_img.shape[1])
        self.w_off_y.setMaximum(self.moving_img.shape[1])
        self.moving_img_z.setMinimum(0)
        self.moving_img_z.setMaximum(self.moving_img.shape[2])
        self.update_ui()

    def save(self):
        filename, filter_type = QtWidgets.QFileDialog.getSaveFileName(
            self,
            "Save parameters",
            filter="JSON file (*.json)",
            options=QtWidgets.QFileDialog.DontUseNativeDialogs
        )
        d = dict(
            x_offset=self.w_off_x.value(),
            y_offset=self.w_off_y.value(),
            x_center=self.w_center_x.value(),
            y_center=self.w_center_y.value(),
            angle=self.w_angle.value(),
            flip_lr=self.w_flip_lr.isChecked(),
            flip_ud=self.w_flip_ud.isChecked()
        )
        with open(filename, "w") as fd:
            json.dump(d, fd, indent=2)

    def update_ui(self):
        if self.fixed_img is not None and self.moving_img is not None:
            self.show_button.setEnabled(True)
        else:
            self.show_button.setDisabled(True)

    def on_center(self, *args):
        if self.fixed_img is not None:
            center_x = self.fixed_img.shape[0] // 2
            center_y = self.fixed_img.shape[1] // 2
            self.w_center_x.setValue(center_x)
            self.w_center_y.setValue(center_y)

    def on_show(self, *args):
        QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor)
        self.figure.clf()
        if self.w_view_choice.currentText() == self.XY_VIEW:
            self.show_xy(self.figure.add_subplot(1, 1, 1))
        else:
            ax_xy = self.figure.add_subplot(2, 2, 1)
            ax_xz = self.figure.add_subplot(2, 2, 2)
            ax_yz = self.figure.add_subplot(2, 2, 4)
            self.show_xy(ax_xy)
            self.show_xz(ax_xz)
            self.show_yz(ax_yz)
        self.canvas.draw()
        QtWidgets.QApplication.restoreOverrideCursor()

    def show_xy(self, axes):
        downsample = self.w_downsample.value()
        fixed_slice = self.fixed_img[::downsample, ::downsample,
                                     self.fixed_img_z.value()].transpose()
        moving_slice = self.moving_img[::downsample, ::downsample,
                                       self.moving_img_z.value()].transpose()
        if self.w_flip_lr.isChecked():
            moving_slice = np.fliplr(moving_slice)
        if self.w_flip_ud.isChecked():
            moving_slice = np.flipud(moving_slice)
        angle = self.w_angle.value() * np.pi / 180
        rot_matrix = np.array([[np.cos(angle), -np.sin(angle)],
                               [np.sin(angle), np.cos(angle)]])
        y, x = np.mgrid[0:fixed_slice.shape[0], 0:fixed_slice.shape[1]]
        center = np.array([self.w_center_y.value(),
                           self.w_center_x.value()]).reshape(1, 2) // downsample
        offset = np.array([self.w_off_y.value(),
                           self.w_off_x.value()]).reshape(1, 2) // downsample
        yx = np.column_stack([y.flatten(), x.flatten()])
        yxt = ((yx - center - offset) @ rot_matrix) + center
        yt, xt = yxt.transpose()
        yt, xt = [_.reshape(fixed_slice.shape) for _ in (yt, xt)]
        cimg = np.zeros((fixed_slice.shape[0], fixed_slice.shape[1], 3), np.float32)
        cimg[:, : , 0] = fixed_slice
        map_coordinates(moving_slice, [yt, xt], cimg[:, :, 1])
        axes.cla()
        clip = np.quantile(cimg.flatten(), .90)
        axes.imshow(np.clip(cimg, 0, clip) / clip)
        self.redo_axes_ticks(axes, self.fixed_img.shape[0], self.fixed_img.shape[1])

    def redo_axes_ticks(self, axes:matplotlib.axes.Axes, x_len:int, y_len:int):
        downsample = self.w_downsample.value()
        x_stops = np.linspace(0, x_len, 6)
        x_stops_downsampled = x_stops / downsample
        axes.set_xticks(x_stops_downsampled)
        axes.set_xticklabels(["%d" % x for x in x_stops])
        y_stops = np.linspace(0, y_len, 6)[::-1]
        y_stops_downsampled = y_stops / downsample
        axes.set_yticks(y_stops_downsampled)
        axes.set_yticklabels(["%d" % y for y in y_stops])

    def show_xz(self, axes):
        downsample = self.w_downsample.value()
        y = self.fixed_img.shape[1] // 2
        min_x = min(self.fixed_img.shape[0], self.moving_img.shape[0])
        min_z = min(self.fixed_img.shape[2], self.moving_img.shape[2])
        fixed_slice = self.fixed_img[:min_x:downsample, y,
                                     :min_z:downsample].transpose()
        moving_slice = self.moving_img[:min_x:downsample, y,
                                       :min_z:downsample].transpose()
        combined = np.stack([fixed_slice, moving_slice, np.zeros_like(fixed_slice)], 2).astype(np.float32)
        clip = np.quantile(combined.flatten(), .90)
        combined = np.clip(combined, 0, clip)
        axes.imshow(combined)
        z_fixed = self.fixed_img_z.value() // downsample
        z_moving = self.moving_img_z.value() // downsample
        axes.plot([0, min_x // downsample], [z_fixed, z_fixed])
        axes.plot([0, min_x // downsample], [z_moving, z_moving])
        self.redo_axes_ticks(axes, min_x, min_z)

    def show_yz(self, axes):
        downsample = self.w_downsample.value()
        x = self.fixed_img.shape[0] // 2
        min_y = min(self.fixed_img.shape[1], self.moving_img.shape[1])
        min_z = min(self.fixed_img.shape[2], self.moving_img.shape[2])
        fixed_slice = self.fixed_img[x,
                                     :min_y:downsample,
                                     :min_z:downsample]
        moving_slice = self.moving_img[x,
                                       :min_y:downsample,
                                       :min_z:downsample]
        combined = np.stack([fixed_slice, moving_slice, np.zeros_like(fixed_slice)], 2).astype(np.float32)
        clip = np.quantile(combined.flatten(), .90)
        combined = np.clip(combined, 0, clip)
        axes.imshow(combined)
        z_fixed = self.fixed_img_z.value() // downsample
        z_moving = self.moving_img_z.value() // downsample
        axes.plot([z_fixed, z_fixed], [0, min_y // downsample])
        axes.plot([z_moving, z_moving], [0, min_y // downsample])
        self.redo_axes_ticks(axes, min_z, min_y)
class HistogramDialog(QDialog):
    """
    This dialog controls settings for plotting a histogram and displays it
    """

    def __init__(self, *args, **kwargs):
        super(HistogramDialog, self).__init__(*args, **kwargs)
        self.appctx = self.parent().appctx
        self.dataset = self.appctx.datasets[self.appctx.current_dataset_idx]
        self.column = list(self.dataset.df)[0]
        self.bins = None
        self.figsize = (12, 5)
        self.dpi = 100
        # Setup UI
        self.setup_ui()

    def setup_ui(self):
        self.setWindowTitle(f"Plot Histogram")
        self.setMinimumWidth(500)
        self.setModal(True)

        layout = QHBoxLayout()
        # Settings
        settings = QGroupBox("Plot Settings")
        left_layout = QFormLayout()
        settings.setLayout(left_layout)
        layout.addWidget(settings)
        # Plot
        right_layout = QVBoxLayout()
        layout.addLayout(right_layout)

        # Canvas
        fig = Figure(figsize=self.figsize, dpi=self.dpi)
        self.canvas = FigureCanvas(fig)
        right_layout.addWidget(self.canvas)

        # Toolbar
        self.canvas_toolbar = NavigationToolbar(self.canvas, self)
        right_layout.addWidget(self.canvas_toolbar)

        # Which column in the dataset
        self.column_btn = QPushButton("None", parent=self)
        self.column_btn.clicked.connect(self.launch_get_column)
        left_layout.addRow("Variable", self.column_btn)

        # Number of bins
        self.bins_sb = QSpinBox(parent=self)
        self.bins_sb.valueChanged.connect(self.update_bin_num)
        self.update_bin_setting()
        left_layout.addRow("Number of Bins", self.bins_sb)

        # Ok/Cancel
        QBtn = QDialogButtonBox.Close

        self.buttonBox = QDialogButtonBox(QBtn)
        right_layout.addWidget(self.buttonBox)
        self.buttonBox.rejected.connect(self.reject)

        # Set Layout
        self.setLayout(layout)

        # Plot inital selection
        self.column_btn.setText(f"{self.column}")
        self.update_canvas()

    def launch_get_column(self):
        """Launch a dialog to set the plotted column from the dataset"""
        column = SelectColumnDialog.get_column(
            columns=list(self.dataset.df), selected=self.column, parent=self
        )
        if column is not None:
            self.column = column
            self.column_btn.setText(f"{self.column}")
            self.update_bin_setting()
            self.update_canvas()

    def update_bin_setting(self):
        var_type = self.dataset.get_types()[self.column]
        var_unique_vals = self.dataset.df[self.column].nunique()
        if var_type == "categorical":
            self.bins_sb.setEnabled(False)
            self.bins_sb.setRange(1, var_unique_vals)
            self.bins_sb.setValue(var_unique_vals)
        else:
            self.bins_sb.setEnabled(True)
            self.bins_sb.setRange(1, var_unique_vals)
            self.bins_sb.setValue(min(100, var_unique_vals))

    def update_canvas(self):
        self.canvas.figure.clear()
        clarite.plot.histogram(
            data=self.dataset.df,
            column=self.column,
            title=f"Histogram of {self.column}",
            figure=self.canvas.figure,
            bins=self.bins,
        )
        self.canvas.draw()

    @pyqtSlot(int)
    def update_bin_num(self, value):
        self.bins = value
        self.update_canvas()
Beispiel #26
0
class StatsWidget(QWidget, FORM_CLASS):

    signalAskCloseWindow = pyqtSignal(name='signalAskCloseWindow')

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

        self.label_progressStats.setText('')

        # Connect
        # noinspection PyUnresolvedReferences
        self.pushButton_saveTable.clicked.connect(self.save_table)
        # noinspection PyUnresolvedReferences
        self.pushButton_saveYValues.clicked.connect(self.save_y_values)
        self.buttonBox_stats.button(QDialogButtonBox.Ok).clicked.connect(
            self.run_stats)
        self.buttonBox_stats.button(QDialogButtonBox.Cancel).clicked.connect(
            self.signalAskCloseWindow.emit)

        # a figure instance to plot on
        self.figure = Figure()
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setMinimumSize(QSize(300, 0))
        self.toolbar = CustomNavigationToolbar(self.canvas, self)
        self.layout_plot.addWidget(self.toolbar)
        self.layout_plot.addWidget(self.canvas)

        self.tab = []

        self.comboBox_blurredLayer.setFilters(
            QgsMapLayerProxyModel.PolygonLayer)
        self.comboBox_statsLayer.setFilters(
            QgsMapLayerProxyModel.PolygonLayer)

    def run_stats(self):
        self.progressBar_stats.setValue(0)
        self.label_progressStats.setText('')
        # noinspection PyArgumentList
        QApplication.processEvents()

        blurred_layer = self.comboBox_blurredLayer.currentLayer()
        stats_layer = self.comboBox_statsLayer.currentLayer()

        try:

            if not blurred_layer or not stats_layer:
                raise NoLayerProvidedException

            crs_blurred_layer = blurred_layer.crs()
            crs_stats_layer = stats_layer.crs()

            if crs_blurred_layer != crs_stats_layer:
                raise DifferentCrsException(
                    epsg1=crs_blurred_layer.authid(),
                    epsg2=crs_stats_layer.authid())

            if blurred_layer == stats_layer:
                raise NoLayerProvidedException

            if not blurred_layer or not stats_layer:
                raise NoLayerProvidedException

            nb_feature_stats = stats_layer.featureCount()
            nb_feature_blurred = blurred_layer.featureCount()
            features_stats = {}

            label_preparing = tr('Preparing index on the stats layer')
            label_creating = tr('Creating index on the stats layer')
            label_calculating = tr('Calculating')

            if Qgis.QGIS_VERSION_INT < 20700:
                self.label_progressStats.setText('%s 1/3' % label_preparing)

                for i, feature in enumerate(stats_layer.getFeatures()):
                    features_stats[feature.id()] = feature
                    percent = int((i + 1) * 100 / nb_feature_stats)
                    self.progressBar_stats.setValue(percent)
                    # noinspection PyArgumentList
                    QApplication.processEvents()

                self.label_progressStats.setText('%s 2/3' % label_creating)
                # noinspection PyArgumentList
                QApplication.processEvents()
                index = QgsSpatialIndex()
                for i, f in enumerate(stats_layer.getFeatures()):
                    index.insertFeature(f)

                    percent = int((i + 1) * 100 / nb_feature_stats)
                    self.progressBar_stats.setValue(percent)
                    # noinspection PyArgumentList
                    QApplication.processEvents()

                self.label_progressStats.setText('%s 3/3' % label_calculating)

            else:
                # If QGIS >= 2.7, we can speed up the spatial index.
                # From 1 min 15 to 7 seconds on my PC.
                self.label_progressStats.setText('%s 1/2' % label_creating)
                # noinspection PyArgumentList
                QApplication.processEvents()
                index = QgsSpatialIndex(stats_layer.getFeatures())
                self.label_progressStats.setText('%s 2/2' % label_calculating)

            # noinspection PyArgumentList
            QApplication.processEvents()
            self.tab = []
            for i, feature in enumerate(blurred_layer.getFeatures()):
                count = 0
                ids = index.intersects(feature.geometry().boundingBox())
                for unique_id in ids:
                    request = QgsFeatureRequest().setFilterFid(unique_id)
                    f = next(stats_layer.getFeatures(request))

                    if f.geometry().intersects(feature.geometry()):
                        count += 1
                self.tab.append(count)

                percent = int((i + 1) * 100 / nb_feature_blurred)
                self.progressBar_stats.setValue(percent)
                # noinspection PyArgumentList
                QApplication.processEvents()

            stats = Stats(self.tab)

            items_stats = [
                'Count(blurred),%d' % nb_feature_blurred,
                'Count(stats),%d' % nb_feature_stats,
                'Min,%d' % stats.min(),
                'Average,%f' % stats.average(),
                'Max,%d' % stats.max(), 'Median,%f' % stats.median(),
                'Range,%d' % stats.range(),
                'Variance,%f' % stats.variance(),
                'Standard deviation,%f' % stats.standard_deviation()
            ]

            self.tableWidget.clear()
            self.tableWidget.setColumnCount(2)
            labels = ['Parameters', 'Values']
            self.tableWidget.setHorizontalHeaderLabels(labels)
            self.tableWidget.setRowCount(len(items_stats))

            for i, item in enumerate(items_stats):
                s = item.split(',')
                self.tableWidget.setItem(i, 0, QTableWidgetItem(s[0]))
                self.tableWidget.setItem(i, 1, QTableWidgetItem(s[1]))
            self.tableWidget.resizeRowsToContents()

            self.draw_plot(self.tab)

        except GeoPublicHealthException as e:
            self.label_progressStats.setText('')
            display_message_bar(msg=e.msg, level=e.level, duration=e.duration)

    def save_table(self):

        if not self.tableWidget.rowCount():
            return False

        csv_string = 'parameter,values\n'

        for i in range(self.tableWidget.rowCount()):
            item_param = self.tableWidget.item(i, 0)
            item_value = self.tableWidget.item(i, 1)
            csv_string += \
                str(item_param.text()) + ',' + item_value.text() + '\n'

        last_directory = get_last_input_path()

        # noinspection PyArgumentList
        output_file, __ = QFileDialog.getSaveFileName(
            parent=self,
            caption=tr('Select file'),
            directory=last_directory,
            filter='CSV (*.csv)')

        if output_file:
            path = dirname(output_file)
            set_last_input_path(path)

            fh = open(output_file, 'w')
            fh.write(csv_string)
            fh.close()
            return True

    def save_y_values(self):

        if not self.tableWidget.rowCount():
            return False

        csv_string = 'parameter,values\n'

        for value in self.tab:
            csv_string += str(value) + '\n'

        last_directory = get_last_input_path()
        # noinspection PyArgumentList
        output_file, __ = QFileDialog.getSaveFileName(
            parent=self,
            caption=tr('Select file'),
            directory=last_directory,
            filter='CSV (*.csv)')

        if output_file:
            path = dirname(output_file)
            set_last_input_path(path)

            fh = open(output_file, 'w')
            fh.write(csv_string)
            fh.close()
            return True

    def draw_plot(self, data):
        # Creating the plot
        # create an axis
        ax = self.figure.add_subplot(111)
        # discards the old graph
        
        # plot data
        ax.plot(data, '*-')

        # ax.set_title('Number of intersections per entity')
        ax.set_xlabel('Blurred entity')
        ax.set_ylabel('Number of intersections')
        ax.grid()

        # refresh canvas
        self.canvas.draw()
Beispiel #27
0
class Window(QWidget):
    xgrid=[]
    data=[]
    fit=[]
    rng1=random.SystemRandom()
    rng2=random.SystemRandom()

    def __init__(self):
        super().__init__()
               
        #---Control buttons---
        self.btnread = QPushButton('Read Data', self)
        self.btnreset = QPushButton('Reset Fitting', self)
        self.btnfit1 = QPushButton('Fit 1x', self)
        self.btnfit100 = QPushButton('Fit 100x', self)

        self.energy=QLabel("Energy: -, steps: 0",self)

        layout=QHBoxLayout(self)
        layout.addWidget(self.btnread)
        layout.addWidget(self.btnreset)
        layout.addWidget(self.btnfit1)
        layout.addWidget(self.btnfit100)
        layout.addWidget(self.energy)
        #layout.addStretch()
        self.control_buttons=QGroupBox()
        self.control_buttons.setLayout(layout)
        #------

        #---Parameter boxes
        self.titleBeta = QLabel("Beta",self)
        self.Beta = QLineEdit("100",self)

        self.titleA = QLabel("A",self)
        self.initA = QLineEdit("1",self)
        self.stepA = QLineEdit("0.1",self)

        self.titleTau = QLabel("Tau",self)
        self.initTau = QLineEdit("130",self)
        self.stepTau = QLineEdit("10",self)

        self.titleT = QLabel("T",self)
        self.initT = QLineEdit("200",self)
        self.stepT = QLineEdit("10",self)

        layout=QGridLayout(self)
        layout.addWidget(self.titleBeta,0,0)
        layout.addWidget(self.Beta,0,1)
        layout.addWidget(self.titleA,1,0)
        layout.addWidget(self.initA,1,1)
        layout.addWidget(self.stepA,1,2)
        layout.addWidget(self.titleTau,2,0)
        layout.addWidget(self.initTau,2,1)
        layout.addWidget(self.stepTau,2,2)
        layout.addWidget(self.titleT,3,0)
        layout.addWidget(self.initT,3,1)
        layout.addWidget(self.stepT,3,2)
        layout.setColumnStretch(2,0)
        self.param_boxes=QGroupBox()
        self.param_boxes.setLayout(layout)
        #------

        #---Main plot---
        self.main_plot = plt.figure()
        self.main_canvas = FigureCanvas(self.main_plot)
        #------ 

        #---Final layout---
        layout=QVBoxLayout(self)
        layout.addWidget(self.main_canvas)
        layout.addWidget(self.control_buttons)
        layout.addWidget(self.param_boxes)
        layout.addStretch()
        self.setLayout(layout)

        self.setWindowTitle('Monte-Carlo fitting')
        self.show()
        #------

        #---Control button actions---
        self.btnread.clicked.connect(self._read_data)
        self.btnreset.clicked.connect(self._reset)
        self.btnfit1.clicked.connect(self._fit1)
        self.btnfit100.clicked.connect(self._fit100)
        #------

    #reads data series from a textfile
    #required format: xvalue whitespace yvalue newline (for each point)
    def _read_data(self):
        #resetting the data and x values arrays and the iteration counter
        self.cnt=0
        self.data=[]
        self.xgrid=[]
        self.energy.setText("Energy: -, steps: 0")

        from PyQt5.QtWidgets import QFileDialog
        fname=QFileDialog.getOpenFileName()[0]
        try:
            fin=open(fname,"r")
        except FileNotFoundError as e:
            print("File not found.")
            return

        try:
            for line in fin:
                self.data.append(float(line.split()[1]))
                self.xgrid.append(float(line.split()[0]))
            self._plot_data()
        except Exception as e:
            print(e.__class__.__name__+": "+str(e))
            print("Invalid file.")
            self.data=[]
            self.xgrid=[]
        fin.close()

    #draws the data points
    def _plot_data(self):
        self.main_plot.clear()
        ax = self.main_plot.add_subplot(111)
        ax.plot(self.data, '+')
        self.main_canvas.draw()

    #Gets the values from the LineEdits
    def _getparams(self):
        #reading the values        
        self.beta=float(self.Beta.text())
        self.A=float(self.initA.text())
        self.dA=float(self.stepA.text())
        self.tau=float(self.initTau.text())
        self.dtau=float(self.stepTau.text())
        self.T=float(self.initT.text())
        self.dT=float(self.stepT.text())

        #initializing the array of fitted values and the energy
        self.E=0
        for i in range(len(self.xgrid)):
            x=self.xgrid[i]
            self.fit.append(self.A*math.exp(-x/self.tau)*math.sin(2*math.pi*x/self.T))
            self.E+=abs(self.data[i]-self.fit[-1])
        

    #Writes the modified parameters back to the LineEdits
    def _setparams(self):        
        self.initA.setText(str(self.A))
        self.initTau.setText(str(self.tau))
        self.initT.setText(str(self.T))

    #Executes one fitting step
    def _fit1(self):
        self.fit=[]
        try:
            self._getparams()
        except Exception as e:
            print(e.__class__.__name__+": "+str(e))
            print("Invalid parameter.")
            return
        self._fit()
        self._plot_fit()
        self._setparams()

    #Executes 100 fitting steps      
    def _fit100(self):
        self.fit=[]
        try:
            self._getparams()
        except Exception as e:
            print(e.__class__.__name__+": "+str(e))
            print("Invalid parameter.")
            return
        [self._fit() for i in range(100)]
        self._plot_fit()
        self._setparams()

    def _func(self, A, tau, T):
        fit=[0]
        E=0
        for i in range(len(self.xgrid)):
            x=self.xgrid[i]
            fit.append(A*math.exp(-x/tau)*math.sin(2*math.pi*x/T))
            E+=abs(self.data[i]-fit[i])
        return fit, E

    #performs a fitting step
    def _fit(self):
        self.cnt+=1

        A=self.A+self.dA*(1-2*self.rng1.random())
        fit, E = self._func(A, self.tau, self.T)
        if((E<self.E) or (self.rng2.random()<math.exp(-self.beta*abs(E-self.E)))):
            self.E=E
            self.fit=fit
            self.A=A

        tau=self.tau+self.dtau*(1-2*self.rng1.random())
        fit, E = self._func(self.A, tau, self.T)
        if((E<self.E) or (self.rng2.random()<math.exp(-self.beta*abs(E-self.E)))):
            self.E=E
            self.fit=fit
            self.tau=tau

        T=self.T+self.dT*(1-2*self.rng1.random())
        fit, E = self._func(self.A, self.tau, T)
        if((E<self.E) or (self.rng2.random()<math.exp(-self.beta*abs(E-self.E)))):
            self.E=E
            self.fit=fit
            self.T=T

    #draws the data points and the fitted curve and writes the energy
    def _plot_fit(self):
        self.main_plot.clear()
        ax = self.main_plot.add_subplot(111)
        ax.plot(self.data, '+')
        ax.plot(self.fit, '-')
        self.main_canvas.draw()

        self.energy.setText("Energy: {:.5E}, steps: {}".format(self.E, self.cnt))

    #resets the iteration counter and deletes the fitted curve
    def _reset(self):
        self.cnt=0
        self._plot_data()
        self.energy=QLabel("Energy: -, steps: 0",self)
Beispiel #28
0
class FS_window(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):  #初始化,没有父类
        super(FS_window, self).__init__(parent)

        self.setupUi(self)
        self.setWindowTitle('基于机器视觉的智慧农药化肥喷洒平台')  #给一个窗口标题
        self.setStyleSheet("#Main_Window{background-color: white}")
        self.setStyleSheet("#stackedWidget{background-color: white}")
        self.train_data.triggered.connect(self.load_traindata)  #链接训练数据
        self.test_data.triggered.connect(self.load_testdata)  #链接测试数据,在界面左上角
        self.picture_data.triggered.connect(self.load_picturedata)  #链接图片数据

        #按钮空间对应界面的不同页面
        self.button_reading.clicked.connect(
            self.topage_1)  #一个按钮可以与一个页面(page)连接
        self.button_preprocessing.clicked.connect(self.topage_2)
        self.button_segemation.clicked.connect(self.topage_3)
        self.button_feature_extraction.clicked.connect(self.topage_4)
        self.button_classification.clicked.connect(self.topage_8)
        self.button_color_feature.clicked.connect(self.topage_5)
        self.button_shape_feature.clicked.connect(self.topage_6)
        self.button_texture_feature.clicked.connect(self.topage_7)

        #先让button灰调,也就是按钮按不了。等它前面的步骤都做完了,再亮回来。
        #self.button_preprocessing.setEnabled(False)
        #self.button_segemation.clicked.setEnabled(False)
        #self.button_feature_extraction.setEnabled(False)
        #self.button_classification.clicked.setEnabled(False)
        #self.button_color_feature.clicked.setEnabled(False)
        #self.button_shape_feature.clicked.setEnabled(False)
        #self.button_texture_feature.clicked.setEnabled(False)

        #按钮控件对应函数
        self.button_get_picture.clicked.connect(
            self.get_picture)  #和后面的函数连接,也就是我们写的函数
        self.button_histogram_equalization.clicked.connect(
            self.histogram_equalization)
        self.button_color_segemation.clicked.connect(self.color_segemation)
        self.button_color_moment.clicked.connect(self.color_moment)  #这写函数还未命名
        self.button_Hu_invariant_moment.clicked.connect(
            self.Hu_invariant_moment)
        self.button_gray_level_co_occurance_matrix.clicked.connect(
            self.gray_level_co_occurance_matrix)
        self.button_classifier.clicked.connect(self.adaboost_classifier)

        ## 画布——对应image(原图)
        self.fig_image = Figure((7, 5))  # 15, 8这里应该只确定了figsize
        self.canvas_image = FigureCanvas(self.fig_image)
        #self.canvas_pca.setParent(self.pca_gongxiantu)
        self.graphicscene_image = QGraphicsScene()
        self.graphicscene_image.addWidget(self.canvas_image)
        self.toolbar_image = NavigationToolbar(self.canvas_image,
                                               self.picture_dujuan_1)

        ## 画布——对应imageH(均衡化后的图)
        self.fig_imageH = Figure((7, 5))  # 15, 8这里应该只确定了figsize
        self.canvas_imageH = FigureCanvas(self.fig_imageH)
        #self.canvas_pca.setParent(self.pca_gongxiantu)
        self.graphicscene_imageH = QGraphicsScene()
        self.graphicscene_imageH.addWidget(self.canvas_imageH)
        self.toolbar_imageH = NavigationToolbar(self.canvas_imageH,
                                                self.picture_imageH)

        ## 画布——对应img_RGB
        self.fig_img_RGB = Figure((7, 5))  # 15, 8这里应该只确定了figsize
        self.canvas_img_RGB = FigureCanvas(self.fig_img_RGB)
        #self.canvas_pca.setParent(self.pca_gongxiantu)
        self.graphicscene_img_RGB = QGraphicsScene()
        self.graphicscene_img_RGB.addWidget(self.canvas_img_RGB)
        self.toolbar_img_RGB = NavigationToolbar(self.canvas_img_RGB,
                                                 self.picture_img_RGB)

    #界面切换
    def topage_1(self):
        self.stackedWidget.setCurrentWidget(self.page_1)

    def topage_2(self):
        self.stackedWidget.setCurrentWidget(self.page_2)

    def topage_3(self):
        self.stackedWidget.setCurrentWidget(self.page_3)

    def topage_4(self):
        self.stackedWidget.setCurrentWidget(self.page_4)

    def topage_5(self):
        self.stackedWidget_2.setCurrentWidget(self.page_5)

    def topage_6(self):
        self.stackedWidget_2.setCurrentWidget(self.page_6)

    def topage_7(self):
        self.stackedWidget_2.setCurrentWidget(self.page_7)

    def topage_8(self):
        self.stackedWidget.setCurrentWidget(self.page_8)

    #导入训练数据
    def load_traindata(self):
        try:
            datafile, _ = QFileDialog.getOpenFileName(self, "选择训练数据")
            print((datafile))
            table = pd.read_csv(datafile)
            print(table)
            # table = xlrd.open_workbook(datafile).sheet_by_index(0)
            nrows = table.shape[0]
            ncols = table.shape[1]
            self.trainWidget.setRowCount(nrows)  #确定行数
            self.trainWidget.setColumnCount(ncols)  #确定列数
            self.train_data = np.zeros((nrows, ncols))  #设初始值,零矩阵
            self.dataArr = np.zeros((nrows, ncols - 1))
            self.LabelArr = np.zeros((nrows, 1))

            for i in range(nrows):
                for j in range(ncols):  #table.at[i, j]
                    self.trainWidget.setItem(
                        i, j, QTableWidgetItem(str(
                            table.at[i, str(j)])))  #这里的trainWidget是界面的东西
                    self.train_data[i, j] = table.at[i, str(j)]  #把数据一个一个导入进去
            for i in range(nrows):
                for j in range(ncols - 1):
                    self.dataArr[i, j] = self.train_data[i, j]
            for i in range(nrows):
                self.LabelArr[i] = self.train_data[i, -1]
            #print(self.dataArr)
            #print(self.LabelArr)
            #print(self.LabelArr.T)
            self.statusbar.showMessage('训练数据已导入')
        except:
            QMessageBox.information(self, 'Warning', '数据为CSV表格',
                                    QMessageBox.Ok)

    #导入测试数据
    def load_testdata(self):
        try:
            datafile, _ = QFileDialog.getOpenFileName(self, "选择测试数据")
            table = pd.read_csv(datafile)
            print(table)
            nrows = table.shape[0]
            ncols = table.shape[1]
            self.testWidget.setRowCount(nrows)
            self.testWidget.setColumnCount(ncols)
            self.test_data = np.zeros((nrows, ncols))
            self.tsetArr = np.zeros((nrows, ncols - 1))
            self.testLabelArr = np.zeros((nrows, 1))

            for i in range(nrows):
                for j in range(ncols):
                    self.testWidget.setItem(
                        i, j, QTableWidgetItem(str(table.at[i, str(j)])))
                    self.test_data[i, j] = table.at[i, str(j)]
            self.statusbar.showMessage('测试数据已导入')
            for i in range(nrows):
                for j in range(ncols - 1):
                    self.tsetArr[i, j] = self.test_data[i, j]
            for i in range(nrows):
                self.testLabelArr[i] = self.test_data[i, -1]
        except:
            QMessageBox.information(self, 'Warning', '数据为CSV表格',
                                    QMessageBox.Ok)

    #选择图片
    def load_picturedata(self):
        try:
            #选择图片
            imgName, imgType = QFileDialog.getOpenFileName(
                self, "打开图片", "img", "*.jpg;*.tif;*.png;;All Files(*)")
            if imgName == "":
                return 0
            self.img = cv2.imread(imgName)
            #qt5读取图片
            #self.jpg = QPixmap(imgName).scaled(self.picture_dujuan_1.width(), self.picture_dujuan_1.height())
        except:
            QMessageBox.information(self, 'Warning', '导入失败', QMessageBox.Ok)

    def get_picture(self):
        try:
            # img=cv2.imread("dujuan_1.jpg")
            #img=cv2.cvtColor(self.jpg,cv2.COLOR_RGB2BGR)
            # gray=cv2.cvtColor(self.img,cv2.COLOR_BGR2GRAY)
            # 修改原图的尺寸
            fx = 0.3
            fy = 0.3
            self.image = cv2.resize(self.img,
                                    dsize=None,
                                    fx=fx,
                                    fy=fy,
                                    interpolation=cv2.INTER_AREA)

            self.fig_image.clear()
            plt = self.fig_image.add_subplot(111)
            plt.imshow(cv2.cvtColor(self.image, cv2.COLOR_BGR2RGB))
            self.canvas_image.draw()
            self.picture_dujuan_1.setScene(self.graphicscene_image)
            self.picture_dujuan_1.show()
            #self.button_preprocessing.setEnabled(True)
        except:
            QMessageBox.information(self, 'Warning', '绘制图片的时候出错',
                                    QMessageBox.Ok)

    def histogram_equalization(self):
        (b, g, r) = cv2.split(self.image)
        bH = cv2.equalizeHist(b)
        gH = cv2.equalizeHist(g)
        rH = cv2.equalizeHist(r)
        self.imageH = cv2.merge((bH, gH, rH))
        self.fig_imageH.clear()
        plt = self.fig_imageH.add_subplot(111)
        plt.imshow(cv2.cvtColor(self.imageH, cv2.COLOR_BGR2RGB))
        self.canvas_imageH.draw()
        self.picture_imageH.setScene(self.graphicscene_imageH)
        self.picture_imageH.show()
        #self.button_segemation.clicked.setEnabled(True)

    def color_segemation(self):
        #基于H分量的双阈值分割

        HSV_img = cv2.cvtColor(self.imageH, cv2.COLOR_BGR2HSV)
        hue = HSV_img[:, :, 0]

        lower_gray = np.array([1, 0, 0])
        upper_gray = np.array([99, 255, 255])

        mask = cv2.inRange(HSV_img, lower_gray, upper_gray)
        # Bitwise-AND mask and original image
        res2 = cv2.bitwise_and(self.imageH, self.imageH, mask=mask)

        # 先将这张图进行二值化

        ret1, thresh1 = cv2.threshold(res2, 0, 255, cv2.THRESH_BINARY)

        # 然后是进行形态学操作
        # 我们采用矩形核(10,10)进行闭运算

        kernel_1 = cv2.getStructuringElement(cv2.MORPH_RECT, (10, 10))
        closing = cv2.morphologyEx(thresh1, cv2.MORPH_CLOSE, kernel_1)

        # 对原图进行RGB三通道分离

        (B, G, R) = cv2.split(self.image)  #之前得到的图

        # 三个通道分别和closing这个模板进行与运算

        mask = cv2.cvtColor(closing, cv2.COLOR_BGR2GRAY)

        and_img_B = cv2.bitwise_and(B, mask)
        and_img_G = cv2.bitwise_and(G, mask)
        and_img_R = cv2.bitwise_and(R, mask)

        # 多通道图像进行混合

        zeros = np.zeros(res2.shape[:2], np.uint8)

        img_RGB = cv2.merge([and_img_R, and_img_G, and_img_B])

        # 下面我先用closing的结果,进一步进行处理

        # 这个颜色空间转来转去的,要小心

        img_BGR = cv2.cvtColor(img_RGB, cv2.COLOR_RGB2BGR)  #这个颜色空间转来转去的,要小心
        HSV_img = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2HSV)
        hue = HSV_img[:, :, 0]

        lower_gray = np.array([1, 0, 0])
        upper_gray = np.array([99, 255, 255])

        mask = cv2.inRange(HSV_img, lower_gray, upper_gray)
        # Bitwise-AND mask and original image
        self.result = cv2.bitwise_and(img_BGR, img_BGR, mask=mask)

        self.fig_img_RGB.clear()
        plt = self.fig_img_RGB.add_subplot(111)
        plt.imshow(cv2.cvtColor(self.result, cv2.COLOR_BGR2RGB))
        self.canvas_img_RGB.draw()
        self.picture_img_RGB.setScene(self.graphicscene_img_RGB)
        self.picture_img_RGB.show()
        #self.button_feature_extraction.setEnabled(True)
        #self.button_color_feature.clicked.setEnabled(True)
        #self.button_shape_feature.clicked.setEnabled(True)
        #self.button_texture_feature.clicked.setEnabled(True)

    def color_moment(self):
        try:
            # Convert BGR to HSV colorspace
            hsv = cv2.cvtColor(self.image, cv2.COLOR_BGR2HSV)
            # Split the channels - h,s,v
            h, s, v = cv2.split(hsv)
            # Initialize the color feature
            color_feature = []
            # N = h.shape[0] * h.shape[1]
            # The first central moment - average
            h_mean = np.mean(h)  # np.sum(h)/float(N)
            s_mean = np.mean(s)  # np.sum(s)/float(N)
            v_mean = np.mean(v)  # np.sum(v)/float(N)
            color_feature.extend([h_mean, s_mean, v_mean])
            # The second central moment - standard deviation
            h_std = np.std(h)  # np.sqrt(np.mean(abs(h - h.mean())**2))
            s_std = np.std(s)  # np.sqrt(np.mean(abs(s - s.mean())**2))
            v_std = np.std(v)  # np.sqrt(np.mean(abs(v - v.mean())**2))
            color_feature.extend([h_std, s_std, v_std])
            # The third central moment - the third root of the skewness
            h_skewness = np.mean(abs(h - h.mean())**3)
            s_skewness = np.mean(abs(s - s.mean())**3)
            v_skewness = np.mean(abs(v - v.mean())**3)
            h_thirdMoment = h_skewness**(1. / 3)
            s_thirdMoment = s_skewness**(1. / 3)
            v_thirdMoment = v_skewness**(1. / 3)
            color_feature.extend([h_thirdMoment, s_thirdMoment, v_thirdMoment])

            self.lineEdit_H_first.setText(str(color_feature[0]))
            self.lineEdit_H_second.setText(str(color_feature[1]))
            self.lineEdit_H_third.setText(str(color_feature[2]))
            self.lineEdit_S_first.setText(str(color_feature[3]))
            self.lineEdit_S_second.setText(str(color_feature[4]))
            self.lineEdit_S_third.setText(str(color_feature[5]))
            self.lineEdit_V_first.setText(str(color_feature[6]))
            self.lineEdit_V_second.setText(str(color_feature[7]))
            self.lineEdit_V_third.setText(str(color_feature[8]))
        except:
            QMessageBox.information(self, 'Warning', '提取颜色矩出错', QMessageBox.Ok)

    def Hu_invariant_moment(self):
        try:
            seg = self.result
            seg_gray = cv2.cvtColor(seg, cv2.COLOR_BGR2GRAY)
            moments = cv2.moments(seg_gray)
            humoments = cv2.HuMoments(moments)
            humoments = np.log(np.abs(humoments))  # 同样建议取对数

            self.fai_1.setText(str(humoments[0]))
            self.fai_2.setText(str(humoments[1]))
            self.fai_3.setText(str(humoments[2]))
            self.fai_4.setText(str(humoments[3]))
            self.fai_5.setText(str(humoments[4]))
            self.fai_6.setText(str(humoments[5]))
            self.fai_7.setText(str(humoments[6]))

        except:
            QMessageBox.information(self, 'Warning', '提取颜色矩出错', QMessageBox.Ok)

    def gray_level_co_occurance_matrix(self):
        try:
            img_shape = self.result.shape

            resized_img = cv2.resize(
                self.result, (int(img_shape[1] / 2), int(img_shape[0] / 2)),
                interpolation=cv2.INTER_CUBIC)

            img_gray = cv2.cvtColor(resized_img, cv2.COLOR_BGR2GRAY)

            gray_level = 16

            #之前的getGlcm(self,img_gray,d_x,d_y)
            d_x = 0
            d_y = 1
            srcdata = img_gray.copy()
            p = [[0.0 for i in range(gray_level)] for j in range(gray_level)]
            (height, width) = img_gray.shape

            #以前的maxGrayLevel(img)
            max_gray_level = 0
            (height, width) = img_gray.shape
            #print(height,width)
            for y in range(height):
                for x in range(width):
                    if img_gray[y][x] > max_gray_level:
                        max_gray_level = img_gray[y][x]

            max_gray_level = max_gray_level + 1

            #若灰度级数大于gray_level,则将图像的灰度级缩小至gray_level,减小灰度共生矩阵的大小
            if max_gray_level > gray_level:
                for j in range(height):
                    for i in range(width):
                        srcdata[j][
                            i] = srcdata[j][i] * gray_level / max_gray_level

            for j in range(height - d_y):
                for i in range(width - d_x):
                    rows = srcdata[j][i]
                    cols = srcdata[j + d_y][i + d_x]
                    p[rows][cols] += 1.0

            for i in range(gray_level):
                for j in range(gray_level):
                    p[i][j] /= float(height * width)

            #之前的feature_computer()
            con = 0.0
            eng = 0.0
            asm = 0.0
            idm = 0.0
            for i in range(gray_level):
                for j in range(gray_level):
                    con += (i - j) * (i - j) * p[i][j]
                    asm += p[i][j] * p[i][j]
                    idm += p[i][j] / (1 + (i - j) * (i - j))
                    if p[i][j] > 0.0:
                        eng -= p[i][j] * math.log(p[i][j])

            self.energy_1.setText(str(asm))
            self.entrophy_1.setText(str(eng))
            self.contrast_ratio.setText(str(con))
            self.inverse_variance.setText(str(idm))
        except:
            QMessageBox.information(self, 'Warning', '提取灰度共生矩阵出错',
                                    QMessageBox.Ok)

        @staticmethod
        def stumpClassify(dataMatrix, dimen, threshVal, threshIneq):
            """
            单层决策树分类函数
            Parameters:
                dataMatrix - 数据矩阵
                dimen - 第dimen列,也就是第几个特征
                threshVal - 阈值
                threshIneq - 标志
            Returns:
                retArray - 分类结果
            """
            retArray = np.ones((np.shape(dataMatrix)[0], 1))  # 初始化retArray为1
            if threshIneq == 'lt':
                retArray[
                    dataMatrix[:, dimen] <= threshVal] = -1.0  # 如果小于阈值,则赋值为-1
            else:
                retArray[dataMatrix[:,
                                    dimen] > threshVal] = -1.0  # 如果大于阈值,则赋值为-1
            return retArray

        @staticmethod
        def buildStump(dataArr, classLabels, D):
            """
            找到数据集上最佳的单层决策树
            Parameters:
                dataArr - 数据矩阵
                classLabels - 数据标签
                D - 样本权重
            Returns:
                bestStump - 最佳单层决策树信息
                minError - 最小误差
                bestClasEst - 最佳的分类结果
            """
            dataMatrix = np.mat(dataArr)
            labelMat = np.mat(classLabels).T
            m, n = np.shape(dataMatrix)
            numSteps = 10.0
            bestStump = {}
            bestClasEst = np.mat(np.zeros((m, 1)))
            minError = float('inf')  # 最小误差初始化为正无穷大
            for i in range(n):  # 遍历所有特征
                rangeMin = dataMatrix[:, i].min()
                rangeMax = dataMatrix[:, i].max()  # 找到特征中最小的值和最大值
                stepSize = (rangeMax - rangeMin) / numSteps  # 计算步长
                for j in range(-1, int(numSteps) + 1):
                    for inequal in [
                            'lt', 'gt'
                    ]:  # 大于和小于的情况,均遍历。lt:less than,gt:greater than
                        threshVal = (rangeMin + float(j) * stepSize)  # 计算阈值
                        predictedVals = FS_window.stumpClassify(
                            dataMatrix, i, threshVal, inequal)  # 计算分类结果
                        errArr = np.mat(np.ones((m, 1)))  # 初始化误差矩阵
                        errArr[predictedVals == labelMat] = 0  # 分类正确的,赋值为0
                        weightedError = D.T * errArr  # 计算误差
                        # print("split: dim %d, thresh %.2f, thresh ineqal: %s, the weighted error is %.3f" % (i, threshVal, inequal, weightedError))
                        if weightedError < minError:  # 找到误差最小的分类方式
                            minError = weightedError
                            bestClasEst = predictedVals.copy()
                            bestStump['dim'] = i
                            bestStump['thresh'] = threshVal
                            bestStump['ineq'] = inequal
            return bestStump, minError, bestClasEst

        # def adaboost_classifier(self):
        #     try:
        #         weakClassArr = []
        #         m = np.shape(self.dataArr)[0]
        #         D = np.mat(np.ones((m, 1)) / m)  # 初始化权重
        #         aggClassEst = np.mat(np.zeros((m, 1)))
        #         numIt = 40
        #         for i in range(numIt):
        #             # bestStump, error, classEst = buildStump(self.dataArr, self.LabelArr, D) 	#构建单层决策树
        #
        #             dataMatrix = np.mat(self.dataArr);
        #             labelMat = np.mat(self.LabelArr).T
        #             m, n = np.shape(dataMatrix)
        #             numSteps = 10.0;
        #             bestStump = {};
        #             bestClasEst = np.mat(np.zeros((m, 1)))
        #             minError = float('inf')  # 最小误差初始化为正无穷大
        #             for i in range(n):  # 遍历所有特征
        #                 rangeMin = dataMatrix[:, i].min();
        #                 rangeMax = dataMatrix[:, i].max()  # 找到特征中最小的值和最大值
        #                 stepSize = (rangeMax - rangeMin) / numSteps  # 计算步长
        #                 for j in range(-1, int(numSteps) + 1):
        #                     for inequal in ['lt', 'gt']:  # 大于和小于的情况,均遍历。lt:less than,gt:greater than
        #                         threshVal = (rangeMin + float(j) * stepSize)  # 计算阈值
        #                         # predictedVals = stumpClassify(dataMatrix, i, threshVal, inequal)#计算分类结果
        #                         dimen = i
        #                         threshIneq = inequal
        #                         retArray = np.ones((np.shape(dataMatrix)[0], 1))  # 初始化retArray为1
        #                         if threshIneq == 'lt':
        #                             retArray[dataMatrix[:, dimen] <= threshVal] = -1.0  # 如果小于阈值,则赋值为-1
        #                         else:
        #                             retArray[dataMatrix[:, dimen] > threshVal] = -1.0
        #
        #                         predictedVals = retArray
        #                         errArr = np.mat(np.ones((m, 1)))  # 初始化误差矩阵
        #                         errArr[predictedVals == labelMat] = 0  # 分类正确的,赋值为0
        #                         weightedError = D.T * errArr  # 计算误差
        #                         # print("split: dim %d, thresh %.2f, thresh ineqal: %s, the weighted error is %.3f" % (i, threshVal, inequal, weightedError))
        #                         if weightedError < minError:  # 找到误差最小的分类方式
        #                             minError = weightedError
        #                             bestClasEst = predictedVals.copy()
        #                             bestStump['dim'] = i
        #                             bestStump['thresh'] = threshVal
        #                             bestStump['ineq'] = inequal
        #             error = minError
        #             classEst = bestClasEst
        #             alpha = float(0.5 * np.log((1.0 - error) / max(error, 1e-16)))  # 计算弱学习算法权重alpha,使error不等于0,因为分母不能为0
        #             bestStump['alpha'] = alpha  # 存储弱学习算法权重
        #             weakClassArr.append(bestStump)  # 存储单层决策树
        #             # print("classEst: ", classEst.T)
        #             expon = np.multiply(-1 * alpha * np.mat(self.LabelArr).T, classEst)  # 计算e的指数项
        #             D = np.multiply(D, np.exp(expon))
        #             D = D / D.sum()  # 根据样本权重公式,更新样本权重
        #             # 计算AdaBoost误差,当误差为0的时候,退出循环
        #             aggClassEst += alpha * classEst  # 计算类别估计累计值
        #             # print("aggClassEst: ", aggClassEst.T)
        #             aggErrors = np.multiply(np.sign(aggClassEst) != np.mat(self.LabelArr).T, np.ones((m, 1)))  # 计算误差
        #             errorRate = aggErrors.sum() / m
        #             # print("total error: ", errorRate)
        #             if errorRate == 0.0: break
        #
        #         # predictions = adaClassify(dataArr, weakClassArr)
        #         datToClass = self.dataArr
        #         classifierArr = self.weakClassArr
        #         dataMatrix = np.mat(datToClass)
        #         m = np.shape(dataMatrix)[0]
        #         aggClassEst = np.mat(np.zeros((m, 1)))
        #         for i in range(len(classifierArr)):  # 遍历所有分类器,进行分类
        #             classEst = stumpClassify(dataMatrix, classifierArr[i]['dim'], classifierArr[i]['thresh'],
        #                                      classifierArr[i]['ineq'])
        #             aggClassEst += classifierArr[i]['alpha'] * classEst
        #             # print(aggClassEst)
        #         predictions = np.sign(aggClassEst)
        #
        #         errArr = np.mat(np.ones((len(self.dataArr), 1)))
        #         print('训练集的错误率:%.3f%%' % float(
        #             errArr[predictions != np.mat(self.LabelArr).T].sum() / len(self.dataArr) * 100))
        #         # predictions = adaClassify(testArr, weakClassArr)
        #         datToClass = self.testArr
        #         classifierArr = self.weakClassArr
        #         dataMatrix = np.mat(datToClass)
        #         m = np.shape(dataMatrix)[0]
        #         aggClassEst = np.mat(np.zeros((m, 1)))
        #         for i in range(len(classifierArr)):  # 遍历所有分类器,进行分类
        #             classEst = stumpClassify(dataMatrix, classifierArr[i]['dim'], classifierArr[i]['thresh'],
        #                                      classifierArr[i]['ineq'])
        #             aggClassEst += classifierArr[i]['alpha'] * classEst
        #             # print(aggClassEst)
        #         predictions = np.sign(aggClassEst)
        #
        #         errArr = np.mat(np.ones((len(self.testArr), 1)))
        #         print('测试集的错误率:%.3f%%' % float(
        #             errArr[predictions != np.mat(self.testLabelArr).T].sum() / len(self.testArr) * 100))
        #
        #
        #     except:
        #         QMessageBox.information(self, 'Warning', '构建分类器出错', QMessageBox.Ok)
        #def adaBoostTrainDS(self):
        def adaboost_classifier(self):
            """
            使用AdaBoost算法提升弱分类器性能
            Parameters:
                dataArr - 数据矩阵
                classLabels - 数据标签
                numIt - 最大迭代次数
            Returns:
                weakClassArr - 训练好的分类器
                aggClassEst - 类别估计累计值
            """
            try:
                weakClassArr = []
                m = np.shape(self.dataArr)[0]
                D = np.mat(np.ones((m, 1)) / m)  # 初始化权重
                aggClassEst = np.mat(np.zeros((m, 1)))
                numIt = 40
                for i in range(numIt):
                    bestStump, error, classEst = FS_Window.buildStump(
                        self.dataArr, self.classLabels, D)  # 构建单层决策树
                    # print("D:",D.T)
                    alpha = float(0.5 * np.log(
                        (1.0 - error) / max(error, 1e-16))
                                  )  # 计算弱学习算法权重alpha,使error不等于0,因为分母不能为0
                    bestStump['alpha'] = alpha  # 存储弱学习算法权重
                    weakClassArr.append(bestStump)  # 存储单层决策树
                    # print("classEst: ", classEst.T)
                    expon = np.multiply(-1 * alpha *
                                        np.mat(self.classLabels).T,
                                        classEst)  # 计算e的指数项
                    D = np.multiply(D, np.exp(expon))
                    D = D / D.sum()  # 根据样本权重公式,更新样本权重
                    # 计算AdaBoost误差,当误差为0的时候,退出循环
                    aggClassEst += alpha * classEst  # 计算类别估计累计值
                    # print("aggClassEst: ", aggClassEst.T)
                    aggErrors = np.multiply(
                        np.sign(aggClassEst) != np.mat(self.classLabels).T,
                        np.ones((m, 1)))  # 计算误差
                    errorRate = aggErrors.sum() / m
                    # print("total error: ", errorRate)
                    if errorRate == 0.0: break  # 误差为0,退出循环
                return weakClassArr, aggClassEst
            except:
                QMessageBox.information(self, 'Warning', '构建分类器出错',
                                        QMessageBox.Ok)
Beispiel #29
0
class VNA(QMainWindow, Ui_VNA):

  max_size = 16384

  def __init__(self):
    super(VNA, self).__init__()
    self.setupUi(self)
    # IP address validator
    rx = QRegExp('^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$')
    self.addrValue.setValidator(QRegExpValidator(rx, self.addrValue))
    # state variables
    self.idle = True
    self.reading = False
    # sweep parameters
    self.sweep_start = 100
    self.sweep_stop = 60000
    self.sweep_size = 600
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    # buffer and offset for the incoming samples
    self.buffer = bytearray(24 * VNA.max_size)
    self.offset = 0
    self.data = np.frombuffer(self.buffer, np.complex64)
    self.adc1 = np.zeros(VNA.max_size, np.complex64)
    self.adc2 = np.zeros(VNA.max_size, np.complex64)
    self.dac1 = np.zeros(VNA.max_size, np.complex64)
    self.open = np.zeros(VNA.max_size, np.complex64)
    self.short = np.zeros(VNA.max_size, np.complex64)
    self.load = np.zeros(VNA.max_size, np.complex64)
    self.dut = np.zeros(VNA.max_size, np.complex64)
    self.mode = 'dut'
    # create figure
    self.figure = Figure()
    self.figure.set_facecolor('none')
    self.canvas = FigureCanvas(self.figure)
    self.plotLayout.addWidget(self.canvas)
    # create navigation toolbar
    self.toolbar = NavigationToolbar(self.canvas, self.plotWidget, False)
    # initialize cursor
    self.cursor = None
    # remove subplots action
    actions = self.toolbar.actions()
    self.toolbar.removeAction(actions[7])
    self.plotLayout.addWidget(self.toolbar)
    # create TCP socket
    self.socket = QTcpSocket(self)
    self.socket.connected.connect(self.connected)
    self.socket.readyRead.connect(self.read_data)
    self.socket.error.connect(self.display_error)
    # connect signals from buttons and boxes
    self.sweepFrame.setEnabled(False)
    self.dutSweep.setEnabled(False)
    self.connectButton.clicked.connect(self.start)
    self.writeButton.clicked.connect(self.write_cfg)
    self.readButton.clicked.connect(self.read_cfg)
    self.openSweep.clicked.connect(self.sweep_open)
    self.shortSweep.clicked.connect(self.sweep_short)
    self.loadSweep.clicked.connect(self.sweep_load)
    self.dutSweep.clicked.connect(self.sweep_dut)
    self.csvButton.clicked.connect(self.write_csv)
    self.s1pButton.clicked.connect(self.write_s1p)
    self.s2pButton.clicked.connect(self.write_s2p)
    self.startValue.valueChanged.connect(self.set_start)
    self.stopValue.valueChanged.connect(self.set_stop)
    self.sizeValue.valueChanged.connect(self.set_size)
    self.rateValue.addItems(['500', '100', '50', '10', '5', '1'])
    self.rateValue.lineEdit().setReadOnly(True)
    self.rateValue.lineEdit().setAlignment(Qt.AlignRight)
    for i in range(0, self.rateValue.count()):
      self.rateValue.setItemData(i, Qt.AlignRight, Qt.TextAlignmentRole)
    self.rateValue.currentIndexChanged.connect(self.set_rate)
    self.corrValue.valueChanged.connect(self.set_corr)
    self.levelValue.valueChanged.connect(self.set_level)
    self.openPlot.clicked.connect(self.plot_open)
    self.shortPlot.clicked.connect(self.plot_short)
    self.loadPlot.clicked.connect(self.plot_load)
    self.dutPlot.clicked.connect(self.plot_dut)
    self.smithPlot.clicked.connect(self.plot_smith)
    self.impPlot.clicked.connect(self.plot_imp)
    self.rcPlot.clicked.connect(self.plot_rc)
    self.swrPlot.clicked.connect(self.plot_swr)
    self.rlPlot.clicked.connect(self.plot_rl)
    self.gainPlot.clicked.connect(self.plot_gain)
    # create timer
    self.startTimer = QTimer(self)
    self.startTimer.timeout.connect(self.timeout)

  def start(self):
    if self.idle:
      self.connectButton.setEnabled(False)
      self.socket.connectToHost(self.addrValue.text(), 1001)
      self.startTimer.start(5000)
    else:
      self.stop()

  def stop(self):
    self.idle = True
    self.socket.abort()
    self.connectButton.setText('Connect')
    self.connectButton.setEnabled(True)
    self.sweepFrame.setEnabled(False)
    self.selectFrame.setEnabled(True)
    self.dutSweep.setEnabled(False)

  def timeout(self):
    self.display_error('timeout')

  def connected(self):
    self.startTimer.stop()
    self.idle = False
    self.set_start(self.startValue.value())
    self.set_stop(self.stopValue.value())
    self.set_size(self.sizeValue.value())
    self.set_rate(self.rateValue.currentIndex())
    self.set_corr(self.corrValue.value())
    self.set_level(self.levelValue.value())
    self.connectButton.setText('Disconnect')
    self.connectButton.setEnabled(True)
    self.sweepFrame.setEnabled(True)
    self.dutSweep.setEnabled(True)

  def read_data(self):
    if not self.reading:
      self.socket.readAll()
      return
    size = self.socket.bytesAvailable()
    self.progress.setValue((self.offset + size) / 24)
    limit = 24 * (self.sweep_size + 1)
    if self.offset + size < limit:
      self.buffer[self.offset:self.offset + size] = self.socket.read(size)
      self.offset += size
    else:
      self.buffer[self.offset:limit] = self.socket.read(limit - self.offset)
      self.adc1 = self.data[0::3]
      self.adc2 = self.data[1::3]
      self.dac1 = self.data[2::3]
      getattr(self, self.mode)[0:self.sweep_size] = self.adc1[1:self.sweep_size + 1] / self.dac1[1:self.sweep_size + 1]
      getattr(self, 'plot_%s' % self.mode)()
      self.reading = False
      self.sweepFrame.setEnabled(True)
      self.selectFrame.setEnabled(True)

  def display_error(self, socketError):
    self.startTimer.stop()
    if socketError == 'timeout':
      QMessageBox.information(self, 'VNA', 'Error: connection timeout.')
    else:
      QMessageBox.information(self, 'VNA', 'Error: %s.' % self.socket.errorString())
    self.stop()

  def set_start(self, value):
    self.sweep_start = value
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    if self.idle: return
    self.socket.write(struct.pack('<I', 0<<28 | int(value * 1000)))

  def set_stop(self, value):
    self.sweep_stop = value
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    if self.idle: return
    self.socket.write(struct.pack('<I', 1<<28 | int(value * 1000)))

  def set_size(self, value):
    self.sweep_size = value
    self.xaxis, self.sweep_step = np.linspace(self.sweep_start, self.sweep_stop, self.sweep_size, retstep = True)
    self.xaxis *= 1000
    if self.idle: return
    self.socket.write(struct.pack('<I', 2<<28 | int(value)))

  def set_rate(self, value):
    if self.idle: return
    rate = [1, 5, 10, 50, 100, 500][value]
    self.socket.write(struct.pack('<I', 3<<28 | int(rate)))

  def set_corr(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 4<<28 | int(value)))

  def set_level(self, value):
    if self.idle: return
    self.socket.write(struct.pack('<I', 5<<28 | int(32767 * np.power(10.0, value / 20.0))))

  def sweep(self):
    if self.idle: return
    self.sweepFrame.setEnabled(False)
    self.selectFrame.setEnabled(False)
    self.socket.write(struct.pack('<I', 6<<28))
    self.offset = 0
    self.reading = True
    self.progress = QProgressDialog('Sweep status', 'Cancel', 0, self.sweep_size + 1)
    self.progress.setModal(True)
    self.progress.setMinimumDuration(1000)
    self.progress.canceled.connect(self.cancel)

  def cancel(self):
    self.offset = 0
    self.reading = False
    self.socket.write(struct.pack('<I', 7<<28))
    self.sweepFrame.setEnabled(True)
    self.selectFrame.setEnabled(True)

  def sweep_open(self):
    self.mode = 'open'
    self.sweep()

  def sweep_short(self):
    self.mode = 'short'
    self.sweep()

  def sweep_load(self):
    self.mode = 'load'
    self.sweep()

  def sweep_dut(self):
    self.mode = 'dut'
    self.sweep()

  def gain(self):
    size = self.sweep_size
    return self.dut[0:size]/self.short[0:size]

  def impedance(self):
    size = self.sweep_size
    return 50.0 * (self.open[0:size] - self.load[0:size]) * (self.dut[0:size] - self.short[0:size]) / ((self.load[0:size] - self.short[0:size]) * (self.open[0:size] - self.dut[0:size]))

  def gamma(self):
    z = self.impedance()
    return (z - 50.0)/(z + 50.0)

  def plot_gain(self):
    if self.cursor is not None: self.cursor.hide().disable()
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.yaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.tick_params('y', color = 'blue', labelcolor = 'blue')
    axes1.yaxis.label.set_color('blue')
    gain = self.gain()
    axes1.plot(self.xaxis, 20.0 * np.log10(np.absolute(gain)), color = 'blue', label = 'Gain')
    axes2 = axes1.twinx()
    axes2.spines['left'].set_color('blue')
    axes2.spines['right'].set_color('red')
    axes1.set_xlabel('Hz')
    axes1.set_ylabel('Gain, dB')
    axes2.set_ylabel('Phase angle')
    axes2.tick_params('y', color = 'red', labelcolor = 'red')
    axes2.yaxis.label.set_color('red')
    axes2.plot(self.xaxis, np.angle(gain, deg = True), color = 'red', label = 'Phase angle')
    self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple')
    self.canvas.draw()

  def plot_magphase(self, data):
    if self.cursor is not None: self.cursor.hide().disable()
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.yaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.tick_params('y', color = 'blue', labelcolor = 'blue')
    axes1.yaxis.label.set_color('blue')
    axes1.plot(self.xaxis, np.absolute(data), color = 'blue', label = 'Magnitude')
    axes2 = axes1.twinx()
    axes2.spines['left'].set_color('blue')
    axes2.spines['right'].set_color('red')
    axes1.set_xlabel('Hz')
    axes1.set_ylabel('Magnitude')
    axes2.set_ylabel('Phase angle')
    axes2.tick_params('y', color = 'red', labelcolor = 'red')
    axes2.yaxis.label.set_color('red')
    axes2.plot(self.xaxis, np.angle(data, deg = True), color = 'red', label = 'Phase angle')
    self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple')
    self.canvas.draw()

  def plot_open(self):
    self.plot_magphase(self.open[0:self.sweep_size])

  def plot_short(self):
    self.plot_magphase(self.short[0:self.sweep_size])

  def plot_load(self):
    self.plot_magphase(self.load[0:self.sweep_size])

  def plot_dut(self):
    self.plot_magphase(self.dut[0:self.sweep_size])

  def plot_smith_grid(self, axes, color):
    load = 50.0
    ticks = np.array([0.0, 0.2, 0.5, 1.0, 2.0, 5.0])
    for tick in ticks * load:
      axis = np.logspace(-4, np.log10(1.0e3), 200) * load
      z = tick + 1.0j * axis
      gamma = (z - load)/(z + load)
      axes.plot(gamma.real, gamma.imag, color = color, linewidth = 0.4, alpha = 0.3)
      axes.plot(gamma.real, -gamma.imag, color = color, linewidth = 0.4, alpha = 0.3)
      z = axis + 1.0j * tick
      gamma = (z - load)/(z + load)
      axes.plot(gamma.real, gamma.imag, color = color, linewidth = 0.4, alpha = 0.3)
      axes.plot(gamma.real, -gamma.imag, color = color, linewidth = 0.4, alpha = 0.3)
      if tick == 0.0:
        axes.text(1.0, 0.0, u'\u221E', color = color, ha = 'left', va = 'center', clip_on = True, fontsize = 18.0)
        axes.text(-1.0, 0.0, u'0\u03A9', color = color, ha = 'left', va = 'bottom', clip_on = True, fontsize = 12.0)
        continue
      lab = u'%d\u03A9' % tick
      x = (tick - load) / (tick + load)
      axes.text(x, 0.0, lab, color = color, ha = 'left', va = 'bottom', clip_on = True, fontsize = 12.0)
      lab = u'j%d\u03A9' % tick
      z =  1.0j * tick
      gamma = (z - load)/(z + load) * 1.05
      x = gamma.real
      y = gamma.imag
      angle = np.angle(gamma) * 180.0 / np.pi - 90.0
      axes.text(x, y, lab, color = color, ha = 'center', va = 'center', clip_on = True, rotation = angle, fontsize = 12.0)
      lab = u'-j%d\u03A9' % tick
      axes.text(x, -y, lab, color = color, ha = 'center', va = 'center', clip_on = True, rotation = -angle, fontsize = 12.0)

  def plot_smith(self):
    if self.cursor is not None: self.cursor.hide().disable()
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(left = 0.0, bottom = 0.0, right = 1.0, top = 1.0)
    axes1 = self.figure.add_subplot(111)
    self.plot_smith_grid(axes1, 'blue')
    gamma = self.gamma()
    plot, = axes1.plot(gamma.real, gamma.imag, color = 'red')
    axes1.axis('equal')
    axes1.set_xlim(-1.12, 1.12)
    axes1.set_ylim(-1.12, 1.12)
    axes1.xaxis.set_visible(False)
    axes1.yaxis.set_visible(False)
    for loc, spine in axes1.spines.items():
      spine.set_visible(False)
    self.cursor = datacursor(plot, formatter = SmithFormatter(self.xaxis), display = 'multiple')
    self.canvas.draw()

  def plot_imp(self):
    self.plot_magphase(self.impedance())

  def plot_rc(self):
    self.plot_magphase(self.gamma())

  def plot_swr(self):
    if self.cursor is not None: self.cursor.hide().disable()
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.yaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.set_xlabel('Hz')
    axes1.set_ylabel('SWR')
    magnitude = np.absolute(self.gamma())
    swr = np.maximum(1.0, np.minimum(100.0, (1.0 + magnitude) / np.maximum(1.0e-20, 1.0 - magnitude)))
    axes1.plot(self.xaxis, swr, color = 'blue', label = 'SWR')
    self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple')
    self.canvas.draw()

  def plot_rl(self):
    if self.cursor is not None: self.cursor.hide().disable()
    matplotlib.rcdefaults()
    self.figure.clf()
    self.figure.subplots_adjust(left = 0.12, bottom = 0.12, right = 0.88, top = 0.98)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.set_major_formatter(FuncFormatter(metric_prefix))
    axes1.set_xlabel('Hz')
    axes1.set_ylabel('Return loss, dB')
    magnitude = np.absolute(self.gamma())
    axes1.plot(self.xaxis, 20.0 * np.log10(magnitude), color = 'blue', label = 'Return loss')
    self.cursor = datacursor(axes = self.figure.get_axes(), formatter = LabelFormatter(), display = 'multiple')
    self.canvas.draw()

  def write_cfg(self):
    dialog = QFileDialog(self, 'Write configuration settings', '.', '*.ini')
    dialog.setDefaultSuffix('ini')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      settings = QSettings(name[0], QSettings.IniFormat)
      self.write_cfg_settings(settings)

  def read_cfg(self):
    dialog = QFileDialog(self, 'Read configuration settings', '.', '*.ini')
    dialog.setDefaultSuffix('ini')
    dialog.setAcceptMode(QFileDialog.AcceptOpen)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      settings = QSettings(name[0], QSettings.IniFormat)
      self.read_cfg_settings(settings)

  def write_cfg_settings(self, settings):
    settings.setValue('addr', self.addrValue.text())
    settings.setValue('start', self.startValue.value())
    settings.setValue('stop', self.stopValue.value())
    settings.setValue('rate', self.rateValue.currentIndex())
    settings.setValue('corr', self.corrValue.value())
    size = self.sizeValue.value()
    settings.setValue('size', size)
    for i in range(0, size):
      settings.setValue('open_real_%d' % i, float(self.open.real[i]))
      settings.setValue('open_imag_%d' % i, float(self.open.imag[i]))
    for i in range(0, size):
      settings.setValue('short_real_%d' % i, float(self.short.real[i]))
      settings.setValue('short_imag_%d' % i, float(self.short.imag[i]))
    for i in range(0, size):
      settings.setValue('load_real_%d' % i, float(self.load.real[i]))
      settings.setValue('load_imag_%d' % i, float(self.load.imag[i]))
    for i in range(0, size):
      settings.setValue('dut_real_%d' % i, float(self.dut.real[i]))
      settings.setValue('dut_imag_%d' % i, float(self.dut.imag[i]))

  def read_cfg_settings(self, settings):
    self.addrValue.setText(settings.value('addr', '192.168.1.100'))
    self.startValue.setValue(settings.value('start', 100, type = int))
    self.stopValue.setValue(settings.value('stop', 60000, type = int))
    self.rateValue.setCurrentIndex(settings.value('rate', 0, type = int))
    self.corrValue.setValue(settings.value('corr', 0, type = int))
    size = settings.value('size', 600, type = int)
    self.sizeValue.setValue(size)
    for i in range(0, size):
      real = settings.value('open_real_%d' % i, 0.0, type = float)
      imag = settings.value('open_imag_%d' % i, 0.0, type = float)
      self.open[i] = real + 1.0j * imag
    for i in range(0, size):
      real = settings.value('short_real_%d' % i, 0.0, type = float)
      imag = settings.value('short_imag_%d' % i, 0.0, type = float)
      self.short[i] = real + 1.0j * imag
    for i in range(0, size):
      real = settings.value('load_real_%d' % i, 0.0, type = float)
      imag = settings.value('load_imag_%d' % i, 0.0, type = float)
      self.load[i] = real + 1.0j * imag
    for i in range(0, size):
      real = settings.value('dut_real_%d' % i, 0.0, type = float)
      imag = settings.value('dut_imag_%d' % i, 0.0, type = float)
      self.dut[i] = real + 1.0j * imag

  def write_csv(self):
    dialog = QFileDialog(self, 'Write csv file', '.', '*.csv')
    dialog.setDefaultSuffix('csv')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      gamma = self.gamma()
      size = self.sizeValue.value()
      fh.write('frequency;open.real;open.imag;short.real;short.imag;load.real;load.imag;dut.real;dut.imag\n')
      for i in range(0, size):
        fh.write('0.0%.8d;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f;%12.9f\n' % (self.xaxis[i], self.open.real[i], self.open.imag[i], self.short.real[i], self.short.imag[i], self.load.real[i], self.load.imag[i], self.dut.real[i], self.dut.imag[i]))
      fh.close()

  def write_s1p(self):
    dialog = QFileDialog(self, 'Write s1p file', '.', '*.s1p')
    dialog.setDefaultSuffix('s1p')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      gamma = self.gamma()
      size = self.sizeValue.value()
      fh.write('# GHz S MA R 50\n')
      for i in range(0, size):
        fh.write('0.0%.8d   %8.6f %7.2f\n' % (self.xaxis[i], np.absolute(gamma[i]), np.angle(gamma[i], deg = True)))
      fh.close()

  def write_s2p(self):
    dialog = QFileDialog(self, 'Write s2p file', '.', '*.s2p')
    dialog.setDefaultSuffix('s2p')
    dialog.setAcceptMode(QFileDialog.AcceptSave)
    dialog.setOptions(QFileDialog.DontConfirmOverwrite)
    if dialog.exec() == QDialog.Accepted:
      name = dialog.selectedFiles()
      fh = open(name[0], 'w')
      gain = self.gain()
      gamma = self.gamma()
      size = self.sizeValue.value()
      fh.write('# GHz S MA R 50\n')
      for i in range(0, size):
        fh.write('0.0%.8d   %8.6f %7.2f   %8.6f %7.2f   0.000000    0.00   0.000000    0.00\n' % (self.xaxis[i], np.absolute(gamma[i]), np.angle(gamma[i], deg = True), np.absolute(gain[i]), np.angle(gain[i], deg = True)))
      fh.close()
Beispiel #30
0
class App(QMainWindow):
    def __init__(self):
        super(App, self).__init__()

        self.title = 'Histogram Equalization'
        top = 100
        left = 100
        width = 680
        height = 500
        self.setGeometry(top, left, width, height)

        self.inputLoaded = None
        self.targetLoaded = None
        # a figure instance to plot on
        self.figure = Figure()
        # Canvas widget that displays figure
        self.canvas = FigureCanvas(self.figure)

        # You can define other things in here
        self.initUI()

    def openInputImage(self):
        # This function is called when the user clicks File->Input Image.
        self.inputLoaded = QFileDialog.getOpenFileName(self, 'Input Image',
                                                       os.getenv('HOME'))
        self.input_img.setPixmap(QPixmap(self.inputLoaded[0]))
        self.plot()

    def openTargetImage(self):
        # This function is called when the user clicks File->Target Image.
        self.targetLoaded = QFileDialog.getOpenFileName(
            self, 'Target Image', os.getenv('HOME'))
        self.target_img.setPixmap(QPixmap(self.targetLoaded[0]))

    def initUI(self):
        # Write GUI initialization code
        menu = self.menuBar()
        file = menu.addMenu('File')

        input_Action = QAction('Open Input', self)

        target_Action = QAction('Open Target', self)

        exit_Action = QAction('Exit', self)

        equalize_hist_action = QAction('Equalize Histogram', self)
        toolbar = self.addToolBar('Toolbar')
        toolbar.addAction(equalize_hist_action)
        equalize_hist_action.triggered.connect(self.histogramButtonClicked)

        file.addAction(input_Action)
        file.addAction(target_Action)
        file.addAction(exit_Action)

        input_Action.triggered.connect(self.openInputImage)
        target_Action.triggered.connect(self.openTargetImage)
        exit_Action.triggered.connect(self.closeApp)

        inner_window = QWidget()
        input_box = QGroupBox('Input', inner_window)
        target_box = QGroupBox('Target', inner_window)
        result_box = QGroupBox('Result', inner_window)

        vbox_input = QVBoxLayout(self)
        input_box.setLayout(vbox_input)
        self.input_img = QLabel()
        vbox_input.addWidget(self.input_img)
        vbox_input.addWidget(self.canvas)
        self.plot()

        vbox_target = QVBoxLayout(self)
        target_box.setLayout(vbox_target)
        self.target_img = QLabel()
        vbox_target.addWidget(self.target_img)

        hbox = QHBoxLayout()
        hbox.addWidget(input_box)
        hbox.addWidget(target_box)
        hbox.addWidget(result_box)
        inner_window.setLayout(hbox)
        self.setCentralWidget(inner_window)

        self.show()

    def closeApp(self):
        self.close()

    def histogramButtonClicked(self):
        if not self.inputLoaded and not self.targetLoaded:
            # Error: "First load input and target images" in MessageBox
            QMessageBox.information(self, "Error",
                                    "First load input and target images")
            return None
        elif not self.inputLoaded:
            # Error: "Load input image" in MessageBox
            QMessageBox.information(self, "Error", "Load input image")
            return None
        elif not self.targetLoaded:
            # Error: "Load target image" in MessageBox
            QMessageBox.information(self, "Error", "Load target image")
            return None

        self.calcHistogram()

    def plot(self):

        # random data
        data = [np.random.random() for i in range(5)]
        # create an axis
        ax = self.figure.add_subplot(111)
        # clear old axis
        ax.clear()
        # plot data
        ax.plot(data)
        # refresh canvas
        self.canvas.draw()

    def calcHistogram(self, I):
        # Calculate histogram
        return NotImplementedError
Beispiel #31
0
class multivariateplotDlg(QtWidgets.QDialog, Ui_multivariateplot):
    def __init__(self, parent=None):
        super(multivariateplotDlg, self).__init__(parent)
        self.setupUi(self)
        self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.CustomizeWindowHint
                            | QtCore.Qt.WindowTitleHint
                            | QtCore.Qt.WindowCloseButtonHint
                            | QtCore.Qt.WindowMaximizeButtonHint)
        self.variablelistWidget.addItems(DS.Lc[DS.Ic])
        self.variablelistWidget.doubleClicked.connect(self.additem_1)
        self.selectedlistWidget.doubleClicked.connect(self.additem_2)
        self.vradioButton.clicked.connect(self.allv)
        self.ApplyButton.clicked.connect(self.redraw)
        self.ResetButton.clicked.connect(self.reset)
        fig = Figure()
        ax = fig.add_subplot(111)
        ax.plot(np.array(0))
        ax.set_xlim([0, 1])
        ax.set_ylim([0, 1])
        self.addmpl(fig)

    def allv(self):
        for i in range(self.variablelistWidget.count()):
            self.selectedlistWidget.addItem(
                self.variablelistWidget.item(i).text())
        self.variablelistWidget.clear()

    def additem_1(self):
        nrow = self.variablelistWidget.currentRow()
        item_str = self.variablelistWidget.item(nrow).text()
        if (self.scattermatrixradioButton.isChecked()):
            maxlim = 6
            if (self.selectedlistWidget.count() > maxlim):
                QtWidgets.QMessageBox.critical(self, 'Error',
                                               "Too many variables!",
                                               QtWidgets.QMessageBox.Ok)
                return ()
        self.variablelistWidget.takeItem(nrow)
        self.selectedlistWidget.addItem(item_str)

    def additem_2(self):
        nrow = self.selectedlistWidget.currentRow()
        item_str = self.selectedlistWidget.item(nrow).text()
        self.variablelistWidget.addItem(item_str)
        self.selectedlistWidget.takeItem(nrow)

    def redraw(self):
        nv = self.selectedlistWidget.count()
        variables = []
        for i in range(nv):
            variables.append(self.selectedlistWidget.item(i).text())
        data = DS.Raw.iloc[DS.Ir, DS.Ic]
        data = data.assign(Lr=DS.Lr[DS.Ir])
        data = data.assign(Cr=DS.Cr[DS.Ir])
        data = data[variables + ['Lr', 'Cr']]
        Nnan = data.isnull().isnull().all().all()
        data = data.dropna()
        Lr = data['Lr'].values
        Cr = data['Cr'].values
        data = data.drop('Lr', axis=1)
        data = data.drop('Cr', axis=1)
        if data.dtypes.all() == 'float' and data.dtypes.all() == 'int':
            QtWidgets.QMessageBox.critical(self,'Error',"Some values are not numbers!",\
                                           QtWidgets.QMessageBox.Ok)
            return ()
        fig = Figure()
        nr, nc = data.shape
        Cc = DS.Cc[DS.Ic]
        Cc = Cc[np.in1d(DS.Lc[DS.Ic], variables)]
        if self.starradioButton.isChecked():
            if (self.selectedlistWidget.count() < 3):
                QtWidgets.QMessageBox.critical(self,'Error',"Too few variables!",\
                                               QtWidgets.QMessageBox.Ok)
                return ()
            mn = data.min()
            mn[mn == 0] = 0.001
            mx = data.max()
            mx[mx == 0] = 0.001
            ranges = list()
            for i in range(len(mn)):
                ranges.append([mn[i], mx[i]])
            radar = ComplexRadar(fig, variables, ranges)
            for i in range(nr):
                y = data.iloc[i, :]
                y[y == 0] = 0.001
                y = y.tolist()
                radar.plot(y)
        elif self.scattermatrixradioButton.isChecked():
            fig = scatterplot_matrix(data.T.values,
                                     variables,
                                     linestyle='none',
                                     marker='o',
                                     color='black',
                                     mfc='none')
            fig.suptitle('Simple Scatterplot Matrix')
        elif self.magnituderadioButton.isChecked():
            ax = fig.add_subplot(111)
            ax.plot(data.values.min(axis=0), 'o', color='red', label='min')
            ax.plot(data.values.max(axis=0), 'o', color='green', label='max')
            ax.legend(loc=4)
            for i in range(nv):
                ax.vlines(i,
                          data.values.min(axis=0)[i],
                          data.values.max(axis=0)[i],
                          linestyles='solid',
                          color=Cc[i])
            #ax.tick_params(axis='x',which='both',bottom='off',top='off',labelbottom='off')
            ax.set_xticklabels([''] + variables + [''])
            ax.set_xlabel('Feature Index')
            ax.set_ylabel('Feature Magnitude')
            ax.set_yscale("log")
            ax.set_xlim([-1, nv])
            ax.xaxis.grid(True)
            ax.yaxis.grid(True)
        elif self.corrradioButton.isChecked():
            fig = plt.figure()
            ax = fig.add_subplot(111)
            cax = ax.matshow(np.corrcoef(data))
            fig.colorbar(cax)
            ax.set_title('Correlation Matrix')
        elif self.covradioButton.isChecked():
            fig = plt.figure()
            ax = fig.add_subplot(111)
            cax = ax.matshow(np.cov(data))
            fig.colorbar(cax)
            ax.set_title('Covariance Matrix')
        elif self.trendradioButton.isChecked():
            ax = fig.add_subplot(111)
            ncol = nc
            nrow = nr
            Lrow = Lr
            color_point = Cr
            color_line = Cc
            if self.rowcheckBox.isChecked():
                ncol = nr
                nrow = nc
                Lrow = np.array(variables)
                color_point = Cc
                color_line = Cr
                data = data.T
            ind = np.array(range(1, nrow + 1))
            for i in range(ncol):
                if self.PcheckBox.isChecked():
                    ax.scatter(ind,
                               data.iloc[:, i],
                               marker='o',
                               color=color_point)
                if self.LcheckBox.isChecked():
                    ax.plot(ind, data.iloc[:, i], color=color_line[i])
                if (nrow > 30):
                    itick = np.linspace(0, nrow - 1, 20).astype(int)
                    ltick = Lrow[itick]
                else:
                    itick = ind
                    ltick = Lrow
                ax.set_xticks(itick)
                ax.set_xticklabels(ltick, rotation='vertical')
                ax.set_xlabel('Object')
        if Nnan:
            ax.annotate('{:04.2f} NaN'.format(Nnan),
                        xy=(0.80, 0.95),
                        xycoords='figure fraction')
        self.rmmpl()
        self.addmpl(fig)

    def reset(self):
        self.variablelistWidget.addItems(DS.getLc().tolist())
        self.selectedlistWidget.clear()
        self.update()

    def addmpl(self, fig):
        self.canvas = FigureCanvas(fig)
        self.mplvl.addWidget(self.canvas)
        self.canvas.draw()
        self.toolbar = NavigationToolbar(self.canvas,
                                         self.mplwindow,
                                         coordinates=True)
        self.mplvl.addWidget(self.toolbar)

    def rmmpl(self, ):
        self.mplvl.removeWidget(self.canvas)
        self.canvas.close()
        self.mplvl.removeWidget(self.toolbar)
        self.toolbar.close()
Beispiel #32
0
class Main(QMainWindow, Ui_MainWindow):
    def __init__(self,specfilename,parfilename=None,wave1=None,wave2=None,numchunks=8,parent=None):
        QtWidgets.QMainWindow.__init__(self, parent)
        #super(Main,self).__init__()
        self.setupUi(self)

        ### Initialize stuff
        self.line_dict = {}
        self.fitpars = None
        self.parinfo = None
        self.linecmts = None
        self.wave1 = wave1
        self.wave2 = wave2
        self.numchunks = numchunks
        self.spls = []
        self.labeltog = 1
        self.pixtog = 0
        self.restog = 1
        self.fitconvtog = 0
        self.lastclick=1334.

        ### Read in spectrum and list of lines to fit
        self.specfilename=specfilename
        self.spectrum = readspec(specfilename)
        self.wave=self.spectrum.wavelength.value
        self.normflux=self.spectrum.flux/self.spectrum.co
        self.normsig=self.spectrum.sig/self.spectrum.co
        cfg.spectrum = self.spectrum
        cfg.wave=self.wave
        cfg.normflux=self.normflux
        cfg.filename=self.specfilename

        if not parfilename==None:
            self.initialpars(parfilename)


        ### Connect signals to slots
        self.fitButton.clicked.connect(self.fitlines)
        self.fitConvBox.clicked.connect(self.togfitconv)
        self.boxLineLabel.clicked.connect(self.toglabels)
        self.boxFitpix.clicked.connect(self.togfitpix)
        self.boxResiduals.clicked.connect(self.togresiduals)
        self.loadParsButton.clicked.connect(self.openParFileDialog)
        self.addLineButton.clicked.connect(self.addLineDialog)
        self.writeParsButton.clicked.connect(self.writeParFileDialog)
        self.writeModelButton.clicked.connect(self.writeModelFileDialog)
        self.writeModelCompButton.clicked.connect(self.writeModelCompFileDialog)
        self.quitButton.clicked.connect(self.quitGui)

        ### Initialize spectral plots
        fig=Figure()
        self.fig=fig
        self.initplot(fig)

        ### Initialize side plot
        sidefig=Figure(figsize=(5.25,2))
        self.sidefig = sidefig
        self.addsidempl(self.sidefig)
        self.sideplot(self.lastclick)  #Dummy initial cenwave setting


    def initplot(self,fig,numchunks=8):
        wlen=len(self.spectrum.wavelength)/numchunks
        self.spls=[]
        if self.wave1==None:  waveidx1=0  # Default to plotting entire spectrum for now
        else: waveidx1=jbg.closest(self.wave,self.wave1)
        if self.fitpars!=None:
                model=joebvpfit.voigtfunc(self.wave,self.datamodel.fitpars)
        sg=jbg.subplotgrid(numchunks)
        for i in range(numchunks):
            self.spls.append(fig.add_subplot(sg[i][0],sg[i][1],sg[i][2]))
            pixs=range(waveidx1+i*wlen,waveidx1+(i+1)*wlen)
            self.spls[i].plot(self.wave[pixs],self.normflux[pixs],linestyle='steps-mid')
            if self.fitpars!=None:
                self.spls[i].plot(self.wave,model,'r')
            self.spls[i].set_xlim(self.wave[pixs[0]],self.wave[pixs[-1]])
            self.spls[i].set_ylim(cfg.ylim)
            self.spls[i].set_xlabel('wavelength',labelpad=0)
            self.spls[i].set_ylabel('relative flux',labelpad=-5)
            self.spls[i].get_xaxis().get_major_formatter().set_scientific(False)
        fig.subplots_adjust(top=0.98,bottom=0.05,left=0.08,right=0.97,wspace=0.15,hspace=0.25)
        self.addmpl(fig)

    def initialpars(self,parfilename):
        ### Deal with initial parameters from line input file
        self.fitpars,self.fiterrors,self.parinfo,self.linecmts = joebvpfit.readpars(parfilename)
        cfg.fitidx=joebvpfit.fitpix(self.wave, self.fitpars) #Set pixels for fit
        cfg.wavegroups=[]
        self.datamodel = LineParTableModel(self.fitpars,self.fiterrors,self.parinfo,linecmts=self.linecmts)
        self.tableView.setModel(self.datamodel)
        self.datamodel.updatedata(self.fitpars,self.fitpars,self.parinfo,self.linecmts)

    def sideplot(self,cenwave,wavebuf=3):
        if len(self.sidefig.axes)==0:
            self.sideax=self.sidefig.add_subplot(111)
        self.sideax.clear()
        self.sideax.plot(self.wave, self.normflux, linestyle='steps-mid')
        if self.pixtog == 1:
            self.sideax.plot(self.wave[cfg.fitidx], self.normflux[cfg.fitidx], 'gs', markersize=4, mec='green')
        model = joebvpfit.voigtfunc(self.wave, self.fitpars)
        res = self.normflux - model
        self.sideax.plot(self.wave, model, 'r')
        if self.restog == 1:
            self.sideax.plot(self.wave, -res, '.', color='black', ms=2)
        self.sideax.plot(self.wave, [0] * len(self.wave), color='gray')

        ### label lines we are trying to fit
        if self.labeltog == 1:
            for j in range(len(self.fitpars[0])):
                labelloc = self.fitpars[0][j] * (1. + self.fitpars[3][j]) + self.fitpars[4][j] / c * \
                                                                            self.fitpars[0][j] * (
                                                                            1. + self.fitpars[3][j])
                label = ' {:.1f}_\nz{:.4f}'.format(self.fitpars[0][j], self.fitpars[3][j])
                self.sideax.text(labelloc, cfg.label_ypos, label, rotation=90, withdash=True, ha='center', va='bottom',
                                 clip_on=True, fontsize=cfg.label_fontsize)

        self.sideax.plot(self.wave, self.normsig, linestyle='steps-mid', color='red', lw=0.5)
        self.sideax.plot(self.wave, -self.normsig, linestyle='steps-mid', color='red', lw=0.5)
        self.sideax.get_xaxis().get_major_formatter().set_scientific(False)
        self.sideax.get_xaxis().get_major_formatter().set_useOffset(False)
        try:
            self.sideax.set_xlim(cenwave-wavebuf,cenwave+wavebuf)
            self.sideax.set_ylim(cfg.ylim)
            self.changesidefig(self.sidefig)
        except TypeError:
            pass
    def fitlines(self):
        print('VPmeasure: Fitting line profile(s)...')
        print(len(self.fitpars[0]),'lines loaded for fitting.')
        if self.fitconvtog:
            self.fitpars, self.fiterrors = joebvpfit.fit_to_convergence(self.wave, self.normflux, self.normsig,
                                                               self.datamodel.fitpars, self.datamodel.parinfo)
        else:
            self.fitpars, self.fiterrors = joebvpfit.joebvpfit(self.wave, self.normflux,self.normsig, self.datamodel.fitpars,self.datamodel.parinfo)
        self.datamodel.updatedata(self.fitpars,self.fiterrors,self.parinfo,self.linecmts)
        self.tableView.resizeColumnsToContents()
        self.updateplot()
        self.sideplot(self.lastclick)

    def togfitconv(self):
        if self.fitconvtog==1: self.fitconvtog=0
        else: self.fitconvtog=1

    def quitGui(self):
        self.deleteLater()
        self.close()

    def toglabels(self):
        if self.labeltog==1: self.labeltog=0
        else: self.labeltog=1
        self.updateplot()

    def togfitpix(self):
        if self.pixtog == 1:
            self.pixtog = 0
        else:
            self.pixtog = 1
        self.updateplot()

    def togresiduals(self):
        if self.restog == 1:
            self.restog = 0
        else:
            self.restog = 1
        self.updateplot()

    def openParFileDialog(self):
        fname = QtWidgets.QFileDialog.getOpenFileName(self, 'Open line parameter file','.')
        fname = str(fname[0])
        if fname != '':
            self.initialpars(fname)

        self.updateplot()

    def writeParFileDialog(self):
        fname = QtWidgets.QFileDialog.getSaveFileName(self, 'Save line parameter file', cfg.VPparoutfile)
        fname = str(fname[0])
        if fname != '':
            joebvpfit.writelinepars(self.datamodel.fitpars, self.datamodel.fiterrors, self.datamodel.parinfo, self.specfilename, fname, self.datamodel.linecmts)

    def writeModelFileDialog(self):
        fname = QtWidgets.QFileDialog.getSaveFileName(self, 'Save model to file', cfg.VPmodeloutfile)
        fname = str(fname[0])
        if fname != '':
            joebvpfit.writeVPmodel(fname, self.wave, self.fitpars, self.normflux, self.normsig)

    def writeModelCompFileDialog(self):
        dirDialog = QtWidgets.QFileDialog(self)
        dirDialog.setFileMode(dirDialog.Directory)
        dirDialog.setOption(dirDialog.ShowDirsOnly, True)
        defDirName = cfg.VPmodeloutfile[:-5]
        dname = dirDialog.getSaveFileName(self, 'Save model to files split by components',defDirName)
        dname = str(dname[0])
        if dname != '':
            joebvpfit.writeVPmodelByComp(dname, self.spectrum,self.fitpars)

    def addLineDialog(self):
        dlgOutput=newLineDialog.get_newline()
        if (dlgOutput != 0):
            if '' not in dlgOutput:
                newlam,newz,newcol,newb,newvel,newvel1,newvel2 = dlgOutput
                self.datamodel.addLine(self.wave,float(newlam), float(newz), float(newcol), float(newb), float(newvel), float(newvel1), float(newvel2))        #dialog=newLineDialog(parent=None)
                self.fitpars = self.datamodel.fitpars
                self.fiterrors = self.datamodel.fiterrors
                self.parinfo = self.datamodel.parinfo
                self.tableView.setModel(self.datamodel)


    def updateplot(self):
        if self.wave1==None:  waveidx1=0  # Default to plotting entire spectrum for now
        else: waveidx1=jbg.closest(self.wave,self.wave1)
        wlen=len(self.spectrum.wavelength)/self.numchunks
        for i,sp in enumerate(self.spls):
                sp.clear()
                prange=range(waveidx1+i*wlen,waveidx1+(i+1)*wlen)
    
                if ((len(self.fitpars[0])>0)):
    
                    sp.plot(self.wave,self.normflux,linestyle='steps-mid')
                    if self.pixtog==1:
                        sp.plot(self.wave[cfg.fitidx], self.normflux[cfg.fitidx], 'gs', markersize=4, mec='green')
                    model=joebvpfit.voigtfunc(self.wave,self.fitpars)
                    res=self.normflux-model
                    sp.plot(self.wave,model,'r')
                    if self.restog==1:
                        sp.plot(self.wave,-res,'.',color='black', ms=2)
                    sp.plot(self.wave,[0]*len(self.wave),color='gray')
    
                    ### label lines we are trying to fit
                    if self.labeltog==1:
                        for j in range(len(self.fitpars[0])):
                            labelloc=self.fitpars[0][j]*(1.+self.fitpars[3][j])+self.fitpars[4][j]/c*self.fitpars[0][j]*(1.+self.fitpars[3][j])
                            label = ' {:.1f}_\nz{:.4f}'.format(self.fitpars[0][j], self.fitpars[3][j])
                            sp.text(labelloc, cfg.label_ypos, label, rotation=90, withdash=True, ha='center', va='bottom', clip_on=True, fontsize=cfg.label_fontsize)
                
    
                sp.plot(self.wave,self.normsig,linestyle='steps-mid',color='red', lw=0.5)
                sp.plot(self.wave,-self.normsig,linestyle='steps-mid',color='red', lw=0.5)
                sp.set_ylim(cfg.ylim)
                sp.set_xlim(self.wave[prange[0]],self.wave[prange[-1]])
                sp.set_xlabel('wavelength (A)', fontsize=cfg.xy_fontsize, labelpad=cfg.x_labelpad)
                sp.set_ylabel('normalized flux', fontsize=cfg.xy_fontsize, labelpad=cfg.y_labelpad)
                sp.get_xaxis().get_major_formatter().set_scientific(False)
                sp.get_xaxis().get_major_formatter().set_useOffset(False)

        self.changefig(self.fig)

    def changefig(self, item):
        #text = str(item.text())
        self.rmmpl()
        self.addmpl(self.fig)

    def changesidefig(self, item):
        #text = str(item.text())
        self.rmsidempl()
        self.addsidempl(self.sidefig)
        
        
    def on_click(self, event):
        self.lastclick=event.xdata
        self.sideplot(self.lastclick)
        
    def addmpl(self, fig):
        self.canvas = FigureCanvas(fig)
        self.canvas.mpl_connect('button_press_event',self.on_click)
        self.mplvl.addWidget(self.canvas)
        self.canvas.draw()
        self.toolbar = NavigationToolbar(self.canvas,self.mplwindow,coordinates=True)
        self.mplvl.addWidget(self.toolbar)

    def addsidempl(self, sidefig):
        self.sidecanvas = FigureCanvas(sidefig)
        self.sidecanvas.setParent(self.sideMplWindow)
        if len(self.sidefig.axes) == 0:
            self.sidemplvl = QVBoxLayout()
        if len(self.sidefig.axes) != 0:
            self.sidemplvl.addWidget(self.sidecanvas)
        if len(self.sidefig.axes) == 0:
            self.sideMplWindow.setLayout(self.sidemplvl)
        self.sidecanvas.draw()

        
    def rmmpl(self,):
        self.mplvl.removeWidget(self.canvas)
        self.canvas.close()
        self.mplvl.removeWidget(self.toolbar)
        self.toolbar.close()

    def rmsidempl(self, ):
        self.sidemplvl.removeWidget(self.sidecanvas)
        self.sidecanvas.close()
Beispiel #33
0
class MainWin(QtWidgets.QMainWindow):
    here = os.path.abspath(os.path.join(os.path.dirname(__file__)))  # to be overloaded
    media = os.path.join(here, "media")
    font_size = 6
    rc_context = {
        'font.family': 'sans-serif',
        'font.sans-serif': ['Tahoma', 'Bitstream Vera Sans', 'Lucida Grande', 'Verdana'],
        'font.size': font_size,
        'figure.titlesize': font_size + 1,
        'axes.labelsize': font_size,
        'legend.fontsize': font_size,
        'xtick.labelsize': font_size - 1,
        'ytick.labelsize': font_size - 1,
        'axes.linewidth': 0.5,
        'axes.xmargin': 0.01,
        'axes.ymargin': 0.01,
        'lines.linewidth': 1.0,
        'grid.alpha': 0.2,
    }

    def __init__(self, main_win=None):
        super().__init__(main_win)

        self.main_win = main_win

        # set the application name and the version
        self.name = rori_name
        self.version = rori_version
        if self.main_win is None:
            self.setWindowTitle('%s v.%s' % (self.name, self.version))
        else:
            self.setWindowTitle('%s' % (self.name,))
        self.setMinimumSize(200, 200)
        self.resize(600, 900)

        # only called when stand-alone (without Sound Speed Manager)
        # noinspection PyArgumentList
        _app = QtCore.QCoreApplication.instance()
        if _app.applicationName() == 'python':
            _app.setApplicationName('%s v.%s' % (self.name, self.version))
            _app.setOrganizationName("HydrOffice")
            _app.setOrganizationDomain("hydroffice.org")
            logger.debug("set application name: %s" % _app.applicationName())

            # set icons
            icon_info = QtCore.QFileInfo(os.path.join(self.media, 'rori.png'))
            self.setWindowIcon(QtGui.QIcon(icon_info.absoluteFilePath()))
            if (sys.platform == 'win32') or (os.name is "nt"):  # is_windows()

                try:
                    # This is needed to display the app icon on the taskbar on Windows 7
                    import ctypes
                    app_id = '%s v.%s' % (self.name, self.version)
                    ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(app_id)
                except AttributeError as e:
                    logger.debug("Unable to change app icon: %s" % e)

        # set palette
        style_info = QtCore.QFileInfo(os.path.join(self.here, 'styles', 'main.stylesheet'))
        style_content = open(style_info.filePath()).read()
        self.setStyleSheet(style_content)

        # mpl figure settings
        self.is_drawn = False
        self.f_dpi = 120  # dots-per-inch
        self.f_sz = (3.0, 6.0)  # inches
        self.tvu_plot = None
        self.thu_plot = None

        self.iho_color = '#E69F24'
        self.noaa_color = '#1C75C3'

        # outline ui
        self.top_widget = QtWidgets.QWidget()
        self.setCentralWidget(self.top_widget)
        self.vbox = QtWidgets.QVBoxLayout()
        self.vbox.setContentsMargins(4, 4, 4, 4)
        self.top_widget.setLayout(self.vbox)

        # ### Settings ###

        self.settings = QtWidgets.QGroupBox("Settings")
        self.vbox.addWidget(self.settings)
        settings_vbox = QtWidgets.QVBoxLayout()
        self.settings.setLayout(settings_vbox)

        label_hbox = QtWidgets.QHBoxLayout()
        settings_vbox.addLayout(label_hbox)
        # stretch
        label_hbox.addStretch()
        # hssd
        text_1ab = QtWidgets.QLabel("")
        text_1ab.setAlignment(QtCore.Qt.AlignCenter)
        text_1ab.setFixedWidth(100)
        label_hbox.addWidget(text_1ab)
        # spacing
        label_hbox.addSpacing(10)
        # specs
        text_1ab = QtWidgets.QLabel("Great Lakes")
        text_1ab.setAlignment(QtCore.Qt.AlignCenter)
        text_1ab.setFixedWidth(100)
        label_hbox.addWidget(text_1ab)
        # spacing
        label_hbox.addSpacing(10)
        # specs
        text_1ab = QtWidgets.QLabel("")
        text_1ab.setAlignment(QtCore.Qt.AlignCenter)
        text_1ab.setFixedWidth(100)
        label_hbox.addWidget(text_1ab)
        # stretch
        label_hbox.addStretch()

        toggle_hbox = QtWidgets.QHBoxLayout()
        settings_vbox.addLayout(toggle_hbox)
        # stretch
        toggle_hbox.addStretch()
        # HSSD
        self.toggle_hssd = QtWidgets.QDial()
        self.toggle_hssd.setNotchesVisible(True)
        self.toggle_hssd.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.toggle_hssd.setRange(0, 1)
        self.toggle_hssd.setValue(0)
        self.toggle_hssd.setFixedSize(QtCore.QSize(50, 50))
        self.toggle_hssd.setInvertedAppearance(False)
        # noinspection PyUnresolvedReferences
        self.toggle_hssd.valueChanged.connect(self.on_settings_changed)
        toggle_hbox.addWidget(self.toggle_hssd)
        # spacing
        toggle_hbox.addSpacing(105)
        # area
        self.toggle_area = QtWidgets.QDial()
        self.toggle_area.setNotchesVisible(True)
        self.toggle_area.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.toggle_area.setRange(0, 2)
        self.toggle_area.setValue(0)
        self.toggle_area.setFixedSize(QtCore.QSize(50, 50))
        self.toggle_area.setInvertedAppearance(False)
        # noinspection PyUnresolvedReferences
        self.toggle_area.valueChanged.connect(self.on_settings_changed)
        toggle_hbox.addWidget(self.toggle_area)
        # spacing0
        toggle_hbox.addSpacing(105)
        # specs
        self.toggle_z = QtWidgets.QDial()
        self.toggle_z.setNotchesVisible(True)
        self.toggle_z.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.toggle_z.setRange(0, 1)
        self.toggle_z.setValue(0)
        self.toggle_z.setFixedSize(QtCore.QSize(50, 50))
        self.toggle_z.setInvertedAppearance(False)
        # noinspection PyUnresolvedReferences
        self.toggle_z.valueChanged.connect(self.on_settings_changed)
        toggle_hbox.addWidget(self.toggle_z)
        # stretch
        toggle_hbox.addStretch()

        label2_hbox = QtWidgets.QHBoxLayout()
        settings_vbox.addLayout(label2_hbox)
        # stretch
        label2_hbox.addStretch()
        # specs
        text_special = QtWidgets.QLabel("HSSD 2018 ")
        text_special.setAlignment(QtCore.Qt.AlignRight)
        text_special.setFixedWidth(70)
        label2_hbox.addWidget(text_special)
        text_2 = QtWidgets.QLabel(" HSSD 2019+")
        text_2.setAlignment(QtCore.Qt.AlignLeft)
        text_2.setFixedWidth(70)
        label2_hbox.addWidget(text_2)
        # stretch
        label2_hbox.addSpacing(10)
        # area
        text_special = QtWidgets.QLabel("Pacific Coast ")
        text_special.setAlignment(QtCore.Qt.AlignRight)
        text_special.setFixedWidth(70)
        label2_hbox.addWidget(text_special)
        text_2 = QtWidgets.QLabel(" Atlantic Coast")
        text_2.setAlignment(QtCore.Qt.AlignLeft)
        text_2.setFixedWidth(70)
        label2_hbox.addWidget(text_2)
        # stretch
        label2_hbox.addSpacing(10)
        # specs
        text_special = QtWidgets.QLabel("Depth ")
        text_special.setAlignment(QtCore.Qt.AlignRight)
        text_special.setFixedWidth(70)
        label2_hbox.addWidget(text_special)
        text_2 = QtWidgets.QLabel(" Elevation")
        text_2.setAlignment(QtCore.Qt.AlignLeft)
        text_2.setFixedWidth(70)
        label2_hbox.addWidget(text_2)
        # stretch
        label2_hbox.addStretch()

        settings_vbox.addSpacing(8)

        hbox = QtWidgets.QHBoxLayout()
        hbox.addStretch()
        watlev_text = QtWidgets.QLabel("Always Dry: ")
        watlev_text.setFixedWidth(100)
        hbox.addWidget(watlev_text)
        self.always_dry_min_value = QtWidgets.QLineEdit()
        self.always_dry_min_value.setFixedWidth(120)
        self.always_dry_min_value.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
        self.always_dry_min_value.setDisabled(True)
        self.always_dry_min_value.setText("")
        hbox.addWidget(self.always_dry_min_value)
        self.always_dry_max_value = QtWidgets.QLineEdit()
        self.always_dry_max_value.setFixedWidth(120)
        self.always_dry_max_value.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
        self.always_dry_max_value.setDisabled(True)
        self.always_dry_max_value.setText("")
        hbox.addWidget(self.always_dry_max_value)
        hbox.addStretch()
        settings_vbox.addLayout(hbox)

        hbox = QtWidgets.QHBoxLayout()
        hbox.addStretch()
        watlev_text = QtWidgets.QLabel("Covers & Uncovers: ")
        watlev_text.setFixedWidth(100)
        hbox.addWidget(watlev_text)
        self.covers_and_uncovers_min_value = QtWidgets.QLineEdit()
        self.covers_and_uncovers_min_value.setFixedWidth(120)
        self.covers_and_uncovers_min_value.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
        self.covers_and_uncovers_min_value.setDisabled(True)
        self.covers_and_uncovers_min_value.setText("")
        hbox.addWidget(self.covers_and_uncovers_min_value)
        self.covers_and_uncovers_max_value = QtWidgets.QLineEdit()
        self.covers_and_uncovers_max_value.setFixedWidth(120)
        self.covers_and_uncovers_max_value.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
        self.covers_and_uncovers_max_value.setDisabled(True)
        self.covers_and_uncovers_max_value.setText("")
        hbox.addWidget(self.covers_and_uncovers_max_value)
        hbox.addStretch()
        settings_vbox.addLayout(hbox)

        hbox = QtWidgets.QHBoxLayout()
        hbox.addStretch()
        watlev_text = QtWidgets.QLabel("Awash: ")
        watlev_text.setFixedWidth(100)
        hbox.addWidget(watlev_text)
        self.awash_min_value = QtWidgets.QLineEdit()
        self.awash_min_value.setFixedWidth(120)
        self.awash_min_value.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
        self.awash_min_value.setDisabled(True)
        self.awash_min_value.setText("")
        hbox.addWidget(self.awash_min_value)
        self.awash_max_value = QtWidgets.QLineEdit()
        self.awash_max_value.setFixedWidth(120)
        self.awash_max_value.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
        self.awash_max_value.setDisabled(True)
        self.awash_max_value.setText("")
        hbox.addWidget(self.awash_max_value)
        hbox.addStretch()
        settings_vbox.addLayout(hbox)

        hbox = QtWidgets.QHBoxLayout()
        hbox.addStretch()
        watlev_text = QtWidgets.QLabel("Always underwater: ")
        watlev_text.setFixedWidth(100)
        hbox.addWidget(watlev_text)
        self.always_underwater_min_value = QtWidgets.QLineEdit()
        self.always_underwater_min_value.setFixedWidth(120)
        self.always_underwater_min_value.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
        self.always_underwater_min_value.setDisabled(True)
        self.always_underwater_min_value.setText("")
        hbox.addWidget(self.always_underwater_min_value)
        self.always_underwater_max_value = QtWidgets.QLineEdit()
        self.always_underwater_max_value.setFixedWidth(120)
        self.always_underwater_max_value.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
        self.always_underwater_max_value.setDisabled(True)
        self.always_underwater_max_value.setText("")
        hbox.addWidget(self.always_underwater_max_value)
        hbox.addStretch()
        settings_vbox.addLayout(hbox)

        # ### Inputs ###

        self.inputs = QtWidgets.QGroupBox("Input")
        self.vbox.addWidget(self.inputs)
        inputs_vbox = QtWidgets.QVBoxLayout()
        self.inputs.setLayout(inputs_vbox)

        # MHW
        hbox = QtWidgets.QHBoxLayout()
        hbox.addStretch()
        self.mhw_text = QtWidgets.QLabel("MHW [m]: ")
        hbox.addWidget(self.mhw_text)
        self.mhw_value = QtWidgets.QLineEdit()
        self.mhw_value.setFixedWidth(60)
        self.mhw_value.setValidator(QtGui.QDoubleValidator(-9999, 9999, 5, self.mhw_value))
        self.mhw_value.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
        self.mhw_value.setText("5.0")
        hbox.addWidget(self.mhw_value)
        depth_text = QtWidgets.QLabel("Depth [m]: ")
        hbox.addWidget(depth_text)
        self.depth_value = QtWidgets.QLineEdit()
        self.depth_value.setFixedWidth(60)
        self.depth_value.setValidator(QtGui.QDoubleValidator(-9999, 9999, 5, self.depth_value))
        self.depth_value.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
        self.depth_value.setText("1.0")
        hbox.addWidget(self.depth_value)
        hbox.addSpacing(16)
        self.calculate = QtWidgets.QPushButton("Run")
        self.calculate.setFixedHeight(28)
        self.calculate.setFixedWidth(42)
        # noinspection PyUnresolvedReferences
        self.calculate.clicked.connect(self.on_calculate)
        hbox.addWidget(self.calculate)
        button = QtWidgets.QPushButton()
        hbox.addWidget(button)
        button.setFixedHeight(GuiSettings.single_line_height())
        button.setFixedWidth(GuiSettings.single_line_height())
        icon_info = QtCore.QFileInfo(os.path.join(self.media, 'small_info.png'))
        button.setIcon(QtGui.QIcon(icon_info.absoluteFilePath()))
        button.setToolTip('Open the manual page')
        button.setStyleSheet(GuiSettings.stylesheet_info_button())
        # noinspection PyUnresolvedReferences
        button.clicked.connect(self.click_open_manual)
        hbox.addStretch()
        inputs_vbox.addLayout(hbox)

        # ### Outputs ###

        self.outputs = QtWidgets.QGroupBox("Outputs")
        self.vbox.addWidget(self.outputs)
        outputs_vbox = QtWidgets.QVBoxLayout()
        self.outputs.setLayout(outputs_vbox)

        outputs_hbox = QtWidgets.QHBoxLayout()
        outputs_vbox.addLayout(outputs_hbox)

        outputs_hbox.addStretch()
        # pic
        self.out_pic_label = QtWidgets.QLabel()
        outputs_hbox.addWidget(self.out_pic_label)

        # info
        hbox = QtWidgets.QHBoxLayout()
        hbox.addStretch()
        out_text_vbox = QtWidgets.QVBoxLayout()
        hbox.addLayout(out_text_vbox)
        self.out_main_label = QtWidgets.QLabel()
        self.out_main_label.setFixedWidth(320)
        self.out_main_label.setStyleSheet("font-weight: bold")
        out_text_vbox.addWidget(self.out_main_label)
        self.out_more_label = QtWidgets.QLabel()
        self.out_more_label.setFixedWidth(320)
        out_text_vbox.addWidget(self.out_more_label)
        hbox.addStretch()
        outputs_hbox.addLayout(hbox)

        outputs_hbox.addStretch()

        # ### PLOTS ###

        # figure and canvas
        with rc_context(self.rc_context):

            self.f = Figure(figsize=self.f_sz, dpi=self.f_dpi)
            self.f.patch.set_alpha(0.0)
            self.c = FigureCanvas(self.f)
            self.c.setParent(self)
            self.c.setFocusPolicy(QtCore.Qt.ClickFocus)  # key for press events!!!
            self.c.setFocus()
            outputs_vbox.addWidget(self.c)

            # axes
            self.levels_ax = self.f.add_subplot(111)
            self.levels_ax.invert_yaxis()

        # toolbar
        self.hbox = QtWidgets.QHBoxLayout()
        outputs_vbox.addLayout(self.hbox)
        # navigation
        self.nav = NavToolbar(canvas=self.c, parent=self.top_widget)
        self.hbox.addWidget(self.nav)

        self.on_settings_changed()
        self.on_first_draw()

    @classmethod
    def is_url(cls, value):
        if len(value) > 7:

            https = "https"
            if value[:len(https)] == https:
                return True

        return False

    @classmethod
    def is_darwin(cls):
        """ Check if the current OS is Mac OS """
        return sys.platform == 'darwin'

    @classmethod
    def is_linux(cls):
        """ Check if the current OS is Linux """
        return sys.platform in ['linux', 'linux2']

    @classmethod
    def is_windows(cls):
        """ Check if the current OS is Windows """
        return (sys.platform == 'win32') or (os.name is "nt")

    @classmethod
    def explore_folder(cls, path):
        """Open the passed path using OS-native commands"""
        if cls.is_url(path):
            import webbrowser
            webbrowser.open(path)
            return True

        if not os.path.exists(path):
            logger.warning('invalid path to folder: %s' % path)
            return False

        path = os.path.normpath(path)

        if cls.is_darwin():
            subprocess.call(['open', '--', path])
            return True

        elif cls.is_linux():
            subprocess.call(['xdg-open', path])
            return True

        elif cls.is_windows():
            subprocess.call(['explorer', path])
            return True

        logger.warning("Unknown/unsupported OS")
        return False

    @classmethod
    def click_open_manual(cls):
        logger.debug("open manual")
        cls.explore_folder(
            "https://www.hydroffice.org/manuals/qctools/user_manual_info.html#rori-your-rock-or-islet-oracle")

    def _draw_grid(self):
        for a in self.f.get_axes():
            a.grid(True)

    def on_first_draw(self):
        """Redraws the figure, it is only called at the first import!!!"""
        with rc_context(self.rc_context):
            # self._set_title()
            self._draw_levels()
            self._draw_grid()
            self.is_drawn = True

    def _draw_levels(self):
        logger.debug("draw levels")

        mhw = float(self.mhw_value.text())
        depth = float(self.depth_value.text())

        if self.toggle_area.value() != 1:
            max_z = 1.5 * max(abs(mhw), abs(depth))
        else:
            max_z = 1.5 * abs(depth)
        alpha = 0.3
        text_color = '#666666'
        text_shift = 0.6

        with rc_context(self.rc_context):

            self.levels_ax.clear()
            # self.levels_ax.set_xlabel('Depth [m]')
            if self.toggle_hssd.value() == 0:  # 2018 HSSD
                if self.toggle_z.value() == 0:
                    self.levels_ax.set_ylabel('Depth [m]')
                    if self.toggle_area.value() == 1:
                        self.levels_ax.axhline(y=0, color='b', linestyle=':')
                        self.levels_ax.text(0.01, -0.01, 'LWD', rotation=0)

                        self.levels_ax.axhline(y=depth, color='r', linestyle='-')
                        self.levels_ax.text(0.01, depth + 0.01, 'depth', rotation=0)

                        self.levels_ax.axhspan(- 1.2192, -max_z, facecolor='orange', alpha=alpha)
                        self.levels_ax.text(text_shift, (- 1.2192 - max_z) / 2.0, 'ALWAYS DRY', color=text_color,
                                            rotation=0)
                        self.levels_ax.axhspan(-0.6096, - 1.2192, facecolor='yellow', alpha=alpha)
                        self.levels_ax.text(text_shift, (-0.6096 - 1.2192) / 2.0, 'COVERS & UNCOVERS',
                                            color=text_color,
                                            rotation=0)
                        self.levels_ax.axhspan(0.6096, -0.6096, facecolor='cyan', alpha=alpha)
                        self.levels_ax.text(text_shift, (0.6096 - 0.6096) / 2.0, 'AWASH', color=text_color,
                                            rotation=0)
                        self.levels_ax.axhspan(max_z, 0.6096, facecolor='#0099ff', alpha=alpha)
                        self.levels_ax.text(text_shift, (max_z + 0.6096) / 2.0, 'ALWAYS UNDERWATER', color=text_color,
                                            rotation=0)
                    else:
                        self.levels_ax.axhline(y=0.0, color='b', linestyle=':')
                        self.levels_ax.text(0.01, 0.01, 'MLLW', rotation=0)

                        self.levels_ax.axhline(y=-mhw, color='orange', linestyle=':')
                        self.levels_ax.text(0.01, -mhw - 0.01, 'MHW', rotation=0)

                        self.levels_ax.axhline(y=depth, color='r', linestyle='-')
                        self.levels_ax.text(0.01, depth + 0.01, 'depth', rotation=0)

                        if self.toggle_area.value() == 0:
                            self.levels_ax.axhspan(-mhw - 0.6096, -max_z, facecolor='orange', alpha=alpha)
                            self.levels_ax.text(text_shift, (-mhw - 0.6096 - max_z) / 2.0, 'ALWAYS DRY',
                                                color=text_color,
                                                rotation=0)
                            self.levels_ax.axhspan(-0.6096, -mhw - 0.6096, facecolor='yellow', alpha=alpha)
                            self.levels_ax.text(text_shift, (-0.6096 - mhw - 0.6096) / 2.0, 'COVERS & UNCOVERS',
                                                color=text_color,
                                                rotation=0)
                            self.levels_ax.axhspan(0.6096, -0.6096, facecolor='cyan', alpha=alpha)
                            self.levels_ax.text(text_shift, (0.6096 - 0.6096) / 2.0, 'AWASH', color=text_color,
                                                rotation=0)
                            self.levels_ax.axhspan(max_z, 0.6096, facecolor='#0099ff', alpha=alpha)
                            self.levels_ax.text(text_shift, (max_z + 0.6096) / 2.0, 'ALWAYS UNDERWATER',
                                                color=text_color,
                                                rotation=0)
                        else:
                            self.levels_ax.axhspan(-mhw - 0.3048, -max_z, facecolor='orange', alpha=alpha)
                            self.levels_ax.text(text_shift, (-mhw - 0.3048 - max_z) / 2.0, 'ALWAYS DRY',
                                                color=text_color,
                                                rotation=0)
                            self.levels_ax.axhspan(-0.3048, -mhw - 0.3048, facecolor='yellow', alpha=alpha)
                            self.levels_ax.text(text_shift, (-0.3048 - mhw - 0.3048) / 2.0, 'COVERS & UNCOVERS',
                                                color=text_color,
                                                rotation=0)
                            self.levels_ax.axhspan(0.3048, -0.3048, facecolor='cyan', alpha=alpha)
                            self.levels_ax.text(text_shift, (0.3048 - 0.3048) / 2.0, 'AWASH', color=text_color,
                                                rotation=0)
                            self.levels_ax.axhspan(max_z, 0.3048, facecolor='#0099ff', alpha=alpha)
                            self.levels_ax.text(text_shift, (max_z + 0.3048) / 2.0, 'ALWAYS UNDERWATER',
                                                color=text_color,
                                                rotation=0)
                    self.levels_ax.set_ylim([max_z, -max_z])

                else:
                    self.levels_ax.set_ylabel('Elevation [m]')
                    if self.toggle_area.value() == 1:
                        self.levels_ax.axhline(y=0, color='b', linestyle=':')
                        self.levels_ax.text(0.01, 0.01, 'LWD', rotation=0)

                        self.levels_ax.axhline(y=-depth, color='r', linestyle='-')
                        self.levels_ax.text(0.01, -depth - 0.01, 'depth', rotation=0)

                        self.levels_ax.axhspan(1.2192, max_z, facecolor='orange', alpha=alpha)
                        self.levels_ax.text(text_shift, (1.2192 + max_z) / 2.0, 'ALWAYS DRY', color=text_color,
                                            rotation=0)
                        self.levels_ax.axhspan(+0.6096, + 1.2192, facecolor='yellow', alpha=alpha)
                        self.levels_ax.text(text_shift, (+0.6096 + 1.2192) / 2.0, 'COVERS & UNCOVERS',
                                            color=text_color,
                                            rotation=0)
                        self.levels_ax.axhspan(-0.6096, 0.6096, facecolor='cyan', alpha=alpha)
                        self.levels_ax.text(text_shift, (-0.6096 + 0.6096) / 2.0, 'AWASH', color=text_color,
                                            rotation=0)
                        self.levels_ax.axhspan(-max_z, -0.6096, facecolor='#0099ff', alpha=alpha)
                        self.levels_ax.text(text_shift, (-max_z - 0.6096) / 2.0, 'ALWAYS UNDERWATER', color=text_color,
                                            rotation=0)
                    else:
                        self.levels_ax.axhline(y=0.0, color='orange', linestyle=':')
                        self.levels_ax.text(0.01, 0.01, 'MHW', rotation=0)

                        self.levels_ax.axhline(y=-mhw, color='b', linestyle=':')
                        self.levels_ax.text(0.01, -mhw - 0.01, 'MLLW', rotation=0)

                        self.levels_ax.axhline(y=-mhw - depth, color='r', linestyle='-')
                        self.levels_ax.text(0.01, -mhw - depth - 0.01, 'depth', rotation=0)

                        if self.toggle_area.value() == 0:
                            self.levels_ax.axhspan(0.6096, max_z, facecolor='orange', alpha=alpha)
                            self.levels_ax.text(text_shift, (0.6096 + max_z) / 2.0, 'ALWAYS DRY', color=text_color,
                                                rotation=0)
                            self.levels_ax.axhspan(-mhw + 0.6096, 0.6096, facecolor='yellow', alpha=alpha)
                            self.levels_ax.text(text_shift, (-mhw + 0.6096 + 0.6096) / 2.0, 'COVERS & UNCOVERS',
                                                color=text_color,
                                                rotation=0)
                            self.levels_ax.axhspan(-mhw - 0.6096, -mhw + 0.6096, facecolor='cyan', alpha=alpha)
                            self.levels_ax.text(text_shift, (-mhw - 0.6096 - mhw + 0.6096) / 2.0, 'AWASH',
                                                color=text_color,
                                                rotation=0)
                            self.levels_ax.axhspan(-max_z, -mhw - 0.6096, facecolor='#0099ff', alpha=alpha)
                            self.levels_ax.text(text_shift, (-max_z - mhw - 0.6096) / 2.0, 'ALWAYS UNDERWATER',
                                                color=text_color,
                                                rotation=0)
                        else:
                            self.levels_ax.axhspan(0.3048, max_z, facecolor='orange', alpha=alpha)
                            self.levels_ax.text(text_shift, (0.3048 + max_z) / 2.0, 'ALWAYS DRY', color=text_color,
                                                rotation=0)
                            self.levels_ax.axhspan(-mhw + 0.3048, 0.3048, facecolor='yellow', alpha=alpha)
                            self.levels_ax.text(text_shift, (-mhw + 0.3048 + 0.3048) / 2.0, 'COVERS & UNCOVERS',
                                                color=text_color,
                                                rotation=0)
                            self.levels_ax.axhspan(-mhw - 0.3048, -mhw + 0.3048, facecolor='cyan', alpha=alpha)
                            self.levels_ax.text(text_shift, (-mhw - 0.3048 - mhw + 0.3048) / 2.0, 'AWASH',
                                                color=text_color,
                                                rotation=0)
                            self.levels_ax.axhspan(-max_z, -mhw - 0.3048, facecolor='#0099ff', alpha=alpha)
                            self.levels_ax.text(text_shift, (-max_z - mhw - 0.3048) / 2.0, 'ALWAYS UNDERWATER',
                                                color=text_color,
                                                rotation=0)

                    self.levels_ax.set_ylim([-max_z, max_z])

            else:  # 2019 HSSD
                if self.toggle_z.value() == 0:
                    self.levels_ax.set_ylabel('Depth [m]')
                    if self.toggle_area.value() == 1:
                        self.levels_ax.axhline(y=0, color='b', linestyle=':')
                        self.levels_ax.text(0.01, -0.01, 'LWD', rotation=0)

                        self.levels_ax.axhline(y=depth, color='r', linestyle='-')
                        self.levels_ax.text(0.01, depth + 0.01, 'depth', rotation=0)

                        self.levels_ax.axhspan(- 0.1, -max_z, facecolor='orange', alpha=alpha)
                        self.levels_ax.text(text_shift, (- 0.1 - max_z) / 2.0, 'ALWAYS DRY', color=text_color,
                                            rotation=0)
                        self.levels_ax.axhspan(-0.1, - 0.1, facecolor='yellow', alpha=alpha)
                        self.levels_ax.text(text_shift, (-0.1 - 0.1) / 2.0, 'COVERS & UNCOVERS',
                                            color=text_color,
                                            rotation=0)
                        self.levels_ax.axhspan(0.1, -0.1, facecolor='cyan', alpha=alpha)
                        self.levels_ax.text(text_shift, (0.1 - 0.1) / 2.0, 'AWASH', color=text_color,
                                            rotation=0)
                        self.levels_ax.axhspan(max_z, 0.1, facecolor='#0099ff', alpha=alpha)
                        self.levels_ax.text(text_shift, (max_z + 0.1) / 2.0, 'ALWAYS UNDERWATER', color=text_color,
                                            rotation=0)
                    else:
                        self.levels_ax.axhline(y=0.0, color='b', linestyle=':')
                        self.levels_ax.text(0.01, 0.01, 'MLLW', rotation=0)

                        self.levels_ax.axhline(y=-mhw, color='orange', linestyle=':')
                        self.levels_ax.text(0.01, -mhw - 0.01, 'MHW', rotation=0)

                        self.levels_ax.axhline(y=depth, color='r', linestyle='-')
                        self.levels_ax.text(0.01, depth + 0.01, 'depth', rotation=0)

                        if self.toggle_area.value() in [0, 2]:
                            self.levels_ax.axhspan(-mhw - 0.1, -max_z, facecolor='orange', alpha=alpha)
                            self.levels_ax.text(text_shift, (-mhw - 0.1 - max_z) / 2.0, 'ALWAYS DRY',
                                                color=text_color,
                                                rotation=0)
                            self.levels_ax.axhspan(-0.1, -mhw - 0.1, facecolor='yellow', alpha=alpha)
                            self.levels_ax.text(text_shift, (-0.1 - mhw - 0.1) / 2.0, 'COVERS & UNCOVERS',
                                                color=text_color,
                                                rotation=0)
                            self.levels_ax.axhspan(0.1, -0.1, facecolor='cyan', alpha=alpha)
                            self.levels_ax.text(text_shift, (0.1 - 0.1) / 2.0, 'AWASH', color=text_color,
                                                rotation=0)
                            self.levels_ax.axhspan(max_z, 0.1, facecolor='#0099ff', alpha=alpha)
                            self.levels_ax.text(text_shift, (max_z + 0.1) / 2.0, 'ALWAYS UNDERWATER',
                                                color=text_color,
                                                rotation=0)
                    self.levels_ax.set_ylim([max_z, -max_z])

                else:
                    self.levels_ax.set_ylabel('Elevation [m]')
                    if self.toggle_area.value() == 1:
                        self.levels_ax.axhline(y=0, color='b', linestyle=':')
                        self.levels_ax.text(0.01, 0.01, 'LWD', rotation=0)

                        self.levels_ax.axhline(y=-depth, color='r', linestyle='-')
                        self.levels_ax.text(0.01, -depth - 0.01, 'depth', rotation=0)

                        self.levels_ax.axhspan(0.1, max_z, facecolor='orange', alpha=alpha)
                        self.levels_ax.text(text_shift, (0.1 + max_z) / 2.0, 'ALWAYS DRY', color=text_color,
                                            rotation=0)
                        self.levels_ax.axhspan(+0., + 0.1, facecolor='yellow', alpha=alpha)
                        self.levels_ax.text(text_shift, (+0.1 + 0.1) / 2.0, 'COVERS & UNCOVERS',
                                            color=text_color,
                                            rotation=0)
                        self.levels_ax.axhspan(-0.1, 0.1, facecolor='cyan', alpha=alpha)
                        self.levels_ax.text(text_shift, (-0.1 + 0.1) / 2.0, 'AWASH', color=text_color,
                                            rotation=0)
                        self.levels_ax.axhspan(-max_z, -0.1, facecolor='#0099ff', alpha=alpha)
                        self.levels_ax.text(text_shift, (-max_z - 0.1) / 2.0, 'ALWAYS UNDERWATER', color=text_color,
                                            rotation=0)
                    else:
                        self.levels_ax.axhline(y=0.0, color='orange', linestyle=':')
                        self.levels_ax.text(0.01, 0.01, 'MHW', rotation=0)

                        self.levels_ax.axhline(y=-mhw, color='b', linestyle=':')
                        self.levels_ax.text(0.01, -mhw - 0.01, 'MLLW', rotation=0)

                        self.levels_ax.axhline(y=-mhw - depth, color='r', linestyle='-')
                        self.levels_ax.text(0.01, -mhw - depth - 0.01, 'depth', rotation=0)

                        if self.toggle_area.value() in [0, 2]:
                            self.levels_ax.axhspan(0.1, max_z, facecolor='orange', alpha=alpha)
                            self.levels_ax.text(text_shift, (0.1 + max_z) / 2.0, 'ALWAYS DRY', color=text_color,
                                                rotation=0)
                            self.levels_ax.axhspan(-mhw + 0.1, 0.1, facecolor='yellow', alpha=alpha)
                            self.levels_ax.text(text_shift, (-mhw + 0.1 + 0.1) / 2.0, 'COVERS & UNCOVERS',
                                                color=text_color,
                                                rotation=0)
                            self.levels_ax.axhspan(-mhw - 0.1, -mhw + 0.1, facecolor='cyan', alpha=alpha)
                            self.levels_ax.text(text_shift, (-mhw - 0.1 - mhw + 0.1) / 2.0, 'AWASH',
                                                color=text_color,
                                                rotation=0)
                            self.levels_ax.axhspan(-max_z, -mhw - 0.1, facecolor='#0099ff', alpha=alpha)
                            self.levels_ax.text(text_shift, (-max_z - mhw - 0.1) / 2.0, 'ALWAYS UNDERWATER',
                                                color=text_color,
                                                rotation=0)
                    self.levels_ax.set_ylim([-max_z, max_z])

    def on_settings_changed(self):
        if self.toggle_hssd.value() == 0:
            logger.debug("draw HSSD 2018")

            if self.toggle_z.value() == 0:
                logger.debug("draw depth")

                if self.toggle_area.value() == 0:
                    logger.debug("West Coast")
                    self.always_dry_min_value.setText("")
                    self.always_dry_max_value.setText("< -0.6096 MHW")
                    self.covers_and_uncovers_min_value.setText(">= -0.6096 MHW")
                    self.covers_and_uncovers_max_value.setText("< -0.6096 MLLW")
                    self.awash_min_value.setText(">= -0.6096 MLLW")
                    self.awash_max_value.setText("< +0.6096 MLLW")
                    self.always_underwater_min_value.setText(">= +0.6096 MLLW")
                    self.always_underwater_max_value.setText("")

                    self.mhw_text.setText("MHW [m]: ")
                    self.mhw_value.setEnabled(True)

                elif self.toggle_area.value() == 1:
                    logger.debug("Great Lakes")
                    self.always_dry_min_value.setText("")
                    self.always_dry_max_value.setText("< -1.2192 LWD")
                    self.covers_and_uncovers_min_value.setText(">= -1.2192 LWD")
                    self.covers_and_uncovers_max_value.setText("< -0.6096 LWD")
                    self.awash_min_value.setText(">= -0.6096 LWD")
                    self.awash_max_value.setText("< +0.6096 LWD")
                    self.always_underwater_min_value.setText(">= +0.6096 LWD")
                    self.always_underwater_max_value.setText("")

                    self.mhw_text.setText("LWD [m]: ")
                    self.mhw_value.setDisabled(True)
                    self.mhw_value.setText("0.0")

                elif self.toggle_area.value() == 2:
                    logger.debug("East Coast")
                    self.always_dry_min_value.setText("")
                    self.always_dry_max_value.setText("< -0.3048 MHW")
                    self.covers_and_uncovers_min_value.setText(">= -0.3048 MHW")
                    self.covers_and_uncovers_max_value.setText("< -0.3048 MLLW")
                    self.awash_min_value.setText(">= -0.3048 MLLW")
                    self.awash_max_value.setText("< +0.3048 MLLW")
                    self.always_underwater_min_value.setText(">= +0.3048 MLLW")
                    self.always_underwater_max_value.setText("")

                    self.mhw_text.setText("MHW [m]: ")
                    self.mhw_value.setEnabled(True)

                else:
                    logger.warning("unknown area")
                    return

            else:
                logger.debug("draw elevation")

                if self.toggle_area.value() == 0:
                    logger.debug("West Coast")
                    self.always_dry_min_value.setText("")
                    self.always_dry_max_value.setText("> +0.6096 MHW")
                    self.covers_and_uncovers_min_value.setText("<= +0.6096 MHW")
                    self.covers_and_uncovers_max_value.setText("> +0.6096 MLLW")
                    self.awash_min_value.setText("<= +0.6096 MLLW")
                    self.awash_max_value.setText("> -0.6096 MLLW")
                    self.always_underwater_min_value.setText("<= -0.6096 MLLW")
                    self.always_underwater_max_value.setText("")

                    self.mhw_text.setText("MHW [m]: ")
                    self.mhw_value.setEnabled(True)

                elif self.toggle_area.value() == 1:
                    logger.debug("Great Lakes")
                    self.always_dry_min_value.setText("")
                    self.always_dry_max_value.setText("> +1.2192 LWD")
                    self.covers_and_uncovers_min_value.setText("<= +1.2192 LWD")
                    self.covers_and_uncovers_max_value.setText("> +0.6096 LWD")
                    self.awash_min_value.setText("<= +0.6096 LWD")
                    self.awash_max_value.setText("> -0.6096 LWD")
                    self.always_underwater_min_value.setText("<= -0.6096 LWD")
                    self.always_underwater_max_value.setText("")

                    self.mhw_text.setText("LWD [m]: ")
                    self.mhw_value.setDisabled(True)

                elif self.toggle_area.value() == 2:
                    logger.debug("East Coast")
                    self.always_dry_min_value.setText("")
                    self.always_dry_max_value.setText("> +0.3048 MHW")
                    self.covers_and_uncovers_min_value.setText("<= +0.3048 MHW")
                    self.covers_and_uncovers_max_value.setText("> +0.3048 MLLW")
                    self.awash_min_value.setText("<= +0.3048 MLLW")
                    self.awash_max_value.setText("> -0.3048 MLLW")
                    self.always_underwater_min_value.setText("<= -0.3048 MLLW")
                    self.always_underwater_max_value.setText("")

                    self.mhw_text.setText("MHW [m]: ")
                    self.mhw_value.setEnabled(True)

                else:
                    logger.warning("unknown area")
                    return
        else:
            logger.debug("draw HSSD 2019")

            if self.toggle_z.value() == 0:
                logger.debug("draw depth")

                if self.toggle_area.value() in [0, 2]:
                    logger.debug("East/West Coast")
                    self.always_dry_min_value.setText("")
                    self.always_dry_max_value.setText("< -0.1 MHW")
                    self.covers_and_uncovers_min_value.setText(">= -0.1 MHW")
                    self.covers_and_uncovers_max_value.setText("<= -0.1 MLLW")
                    self.awash_min_value.setText("> -0.1 MLLW")
                    self.awash_max_value.setText("<= +0.1 MLLW")
                    self.always_underwater_min_value.setText("> +0.1 MLLW")
                    self.always_underwater_max_value.setText("")

                    self.mhw_text.setText("MHW [m]: ")
                    self.mhw_value.setEnabled(True)

                elif self.toggle_area.value() == 1:
                    logger.debug("Great Lakes")
                    self.always_dry_min_value.setText("")
                    self.always_dry_max_value.setText("< -0.1 LWD")
                    self.covers_and_uncovers_min_value.setText(">= -0.1 LWD")
                    self.covers_and_uncovers_max_value.setText("<= -0.1 LWD")
                    self.awash_min_value.setText("> -0.1 LWD")
                    self.awash_max_value.setText("<= +0.1 LWD")
                    self.always_underwater_min_value.setText("> +0.1 LWD")
                    self.always_underwater_max_value.setText("")

                    self.mhw_text.setText("LWD [m]: ")
                    self.mhw_value.setDisabled(True)

                else:
                    logger.warning("unknown area")
                    return

            else:
                logger.debug("draw elevation")

                if self.toggle_area.value() in [0, 2]:
                    logger.debug("East/West Coast")
                    self.always_dry_min_value.setText("")
                    self.always_dry_max_value.setText("> +0.1 MHW")
                    self.covers_and_uncovers_min_value.setText("<= +0.1 MHW")
                    self.covers_and_uncovers_max_value.setText(">= +0.1 MLLW")
                    self.awash_min_value.setText("< +0.1 MLLW")
                    self.awash_max_value.setText(">= -0.1 MLLW")
                    self.always_underwater_min_value.setText("< -0.1 MLLW")
                    self.always_underwater_max_value.setText("")

                    self.mhw_text.setText("MHW [m]: ")
                    self.mhw_value.setEnabled(True)

                elif self.toggle_area.value() == 1:
                    logger.debug("Great Lakes")
                    self.always_dry_min_value.setText("")
                    self.always_dry_max_value.setText("> +0.1 LWD")
                    self.covers_and_uncovers_min_value.setText("<= +0.1 LWD")
                    self.covers_and_uncovers_max_value.setText(">= +0.1 LWD")
                    self.awash_min_value.setText("< +0.1 LWD")
                    self.awash_max_value.setText(">= -0.1 LWD")
                    self.always_underwater_min_value.setText("< -0.1 LWD")
                    self.always_underwater_max_value.setText("")

                    self.mhw_text.setText("LWD [m]: ")
                    self.mhw_value.setDisabled(True)
                    self.mhw_value.setText("0.0")

                else:
                    logger.warning("unknown area")
                    return

        self.on_calculate()

    def on_calculate(self):
        logger.debug("calculate")

        mhw = float(self.mhw_value.text())
        depth = float(self.depth_value.text())
        elevation = None
        watlev = None

        wl_dict = {
            "Always Dry": None,
            "Awash": 5,
            "Covers & Uncovers": 4,
            "Always Underwater": 3
        }

        if self.toggle_hssd.value() == 0:
            logger.debug("draw HSSD 2018")

            if self.toggle_area.value() == 1:
                if depth < - 1.2192:
                    logger.debug("Islet")
                    elevation = -depth
                else:
                    logger.debug("Rock")
                    if depth < -0.6096:
                        watlev = "Covers & Uncovers"
                    elif depth < 0.6096:
                        watlev = "Awash"
                    else:
                        watlev = "Always Underwater"

                    logger.debug("%s [%s]" % (watlev, wl_dict[watlev]))

            else:

                if self.toggle_area.value() == 0:
                    if depth < (-mhw - 0.6096):
                        logger.debug("Islet")
                        elevation = -mhw - depth
                    else:
                        logger.debug("Rock")
                        if depth < -0.6096:
                            watlev = "Covers & Uncovers"
                        elif depth < 0.6096:
                            watlev = "Awash"
                        else:
                            watlev = "Always Underwater"

                        logger.debug("%s [%s]" % (watlev, wl_dict[watlev]))

                else:
                    if depth < (-mhw - 0.3048):
                        logger.debug("Islet")
                        elevation = -mhw - depth
                    else:
                        logger.debug("Rock")
                        if depth < -0.3048:
                            watlev = "Covers & Uncovers"
                        elif depth < 0.3048:
                            watlev = "Awash"
                        else:
                            watlev = "Always Underwater"

                        logger.debug("%s [%s]" % (watlev, wl_dict[watlev]))

        else:
            logger.debug("draw HSSD 2019")

            if self.toggle_area.value() == 1:
                if depth < - 0.1:
                    logger.debug("Islet")
                    elevation = -depth
                else:
                    logger.debug("Rock")
                    if depth <= -0.1:
                        watlev = "Covers & Uncovers"
                    elif depth <= 0.1:
                        watlev = "Awash"
                    else:
                        watlev = "Always Underwater"

                    logger.debug("%s [%s]" % (watlev, wl_dict[watlev]))

            else:
                if self.toggle_area.value() in [0, 2]:
                    if depth < (-mhw - 0.1):
                        logger.debug("Islet")
                        elevation = -mhw - depth
                    else:
                        logger.debug("Rock")
                        if depth <= -0.1:
                            watlev = "Covers & Uncovers"
                        elif depth <= 0.1:
                            watlev = "Awash"
                        else:
                            watlev = "Always Underwater"

                        logger.debug("%s [%s]" % (watlev, wl_dict[watlev]))

        if elevation is not None:
            logger.debug("elevation: %.3f" % elevation)
            pix = QtGui.QPixmap(os.path.join(self.media, 'islet.png'))
            self.out_pic_label.setPixmap(pix.scaled(60, 60, QtCore.Qt.KeepAspectRatio))
            self.out_main_label.setText("I S L E T")
            self.out_more_label.setText("ELEVAT=%.3f" % elevation)
        else:
            pix = QtGui.QPixmap(os.path.join(self.media, 'rock.png'))
            self.out_pic_label.setPixmap(pix.scaled(60, 60, QtCore.Qt.KeepAspectRatio))
            self.out_main_label.setText("R O C K")
            self.out_more_label.setText("VALSOU=%.3f, WATLEV=%s[%s]" % (depth, watlev, wl_dict[watlev]))

        self._draw_levels()
        self._draw_grid()
        self.c.draw()
Beispiel #34
0
class AppForm(QMainWindow):
    def __init__(self, parent=None):
        self.bsz = 5.0  # (arcsec)
        self.nnn = 500
        self.dsx = self.bsz / self.nnn

        self.xi1 = np.linspace(-self.bsz / 2.0, self.bsz / 2.0,
                               self.nnn) + 0.5 * self.dsx
        self.xi2 = np.linspace(-self.bsz / 2.0, self.bsz / 2.0,
                               self.nnn) + 0.5 * self.dsx
        self.xi1, self.xi2 = np.meshgrid(self.xi1, self.xi2)

        self.file_name = "./ds9_images.png"
        a_tmp = Image.open(self.file_name)
        a_tmp = np.array(a_tmp)
        self.lgals = np.flipud(a_tmp[:, :, 0] / 256.0)

        self.srcs_name = "./ds9_srcs.png"
        s_tmp = Image.open(self.srcs_name)
        s_tmp = np.array(s_tmp)
        # # sgals_tmp = (s_tmp[:,:,0]+s_tmp[:,:,1]+s_tmp[:,:,2])/256.0/2.0
        # # sgals_tmp = (s_tmp[:,:,0])/256.0
        # self.sgals = self.lgals*0.0
        # xoff = -15
        # yoff = -10
        # self.sgals[200+xoff:233+xoff,200+yoff:233+yoff] = sgals_tmp
        self.sgals = np.flipud(s_tmp[:, :, 0] / 256.0)

        st_re = nbins / 2
        st_x1 = nbins / 2
        st_x2 = nbins / 2
        st_rc = 0 * nbins
        st_ql = nbins / 2
        st_pa = nbins / 3

        # self.lpar = np.asarray([(st_x1*self.bsz/nbins-self.bsz/2.0),(st_x2*self.bsz/nbins-self.bsz/2.0),st_re*4.0/nbins,st_rc*0.0,st_ql*1.0/nbins,st_pa*360.0/nbins])
        self.lpar = np.asarray([(st_x1 * self.bsz / nbins - self.bsz / 2.0 +
                                 self.bsz / nbins / 2.0),
                                (st_x2 * self.bsz / nbins - self.bsz / 2.0 +
                                 self.bsz / nbins / 2.0), st_re * 2.0 / nbins,
                                st_rc * 0.0, st_ql * 1.0 / nbins,
                                st_pa * 360.0 / nbins])
        #----------------------------------------------------------------------
        QMainWindow.__init__(self, parent)
        self.setWindowTitle('Interactive Lens Modeling')

        self.create_menu()
        self.create_main_frame()
        self.create_status_bar()

        self.textbox.setText('67.26 0.32 0.68')
        self.on_draw()

        #= QLabel("Re = %.2f" % self.lpar[2])
        #label_nombre.setText("hola")

    def save_plot(self):
        file_choices = "PNG (*.png)|*.png"

        path = QFileDialog.getSaveFileName(self, 'Save file', '', file_choices)
        if path:
            self.canvas.print_figure(path, dpi=self.dpi)
            self.statusBar().showMessage('Saved to %s' % path, 2000)

    def on_about(self):
        msg = """ A demo of using PyQt with matplotlib:

         * Use the matplotlib navigation bar
         * Add values to the text box and press Enter (or click "Draw")
         * Show or hide the grid
         * Drag the slider to modify the width of the bars
         * Save the plot to a file using the File menu
         * Click on a bar to receive an informative message
        """
        QMessageBox.about(self, "About the demo", msg.strip())

    def on_pick(self, event):
        # The event received here is of the type
        # matplotlib.backend_bases.PickEvent
        #
        # It carries lots of information, of which we're using
        # only a small amount here.
        #
        box_points = event.artist.get_bbox().get_points()
        msg = "You've clicked on a bar with coords:\n %s" % box_points

        QMessageBox.information(self, "Click!", msg)

    def on_draw(self):
        """ Redraws the figure
        """

        l_xcen = self.slider_x1.value(
        ) * self.bsz / nbins - self.bsz / 2.0 + self.bsz / nbins / 2.0  # x position of center (also try (0.0,0.14)
        l_ycen = self.slider_x2.value(
        ) * self.bsz / nbins - self.bsz / 2.0 + self.bsz / nbins / 2.0  # y position of center
        l_re = self.slider_re.value() * 2.0 / nbins  # Einstein radius of lens.
        l_rc = 0.0  # Core size of lens (in units of Einstein radius).
        l_axrat = self.slider_ql.value() * 1.0 / nbins  # Axis ratio of lens.
        l_pa = self.slider_la.value() * 360.0 / nbins  # Orintation of lens.

        self.lpar = np.asarray([l_xcen, l_ycen, l_re, l_rc, l_axrat, l_pa])
        #----------------------------------------------------------------------
        g_amp = 1.0  # peak brightness value
        g_sig = self.slider_rh.value(
        ) * 0.5 / nbins  # Gaussian "sigma" (i.e., size)
        g_xcen = self.slider_y1.value(
        ) * self.bsz / 4.0 / nbins - self.bsz / 8.0 + self.bsz / nbins / 8.0  # x position of center (also try (0.0,0.14)
        g_ycen = self.slider_y2.value(
        ) * self.bsz / 4.0 / nbins - self.bsz / 8.0 + self.bsz / nbins / 8.0  # y position of center
        g_axrat = self.slider_qs.value(
        ) * 1.0 / nbins  # minor-to-major axis ratio
        g_pa = self.slider_sa.value(
        ) * 360.0 / nbins  # major-axis position angle (degrees) c.c.w. from x axis

        self.spar = np.asarray([g_xcen, g_ycen, g_sig, g_amp, g_axrat, g_pa])

        print "plot***", self.spar
        #----------------------------------------------------------------------
        g_limage, g_source, mua, yi1, yi2 = ll.lensed_images(
            self.xi1, self.xi2, self.lpar, self.spar)
        #--------------------------lens images contour------------------------

        levels = [
            0.5,
        ]
        levels_imgs = [0.0, 0.08, 0.1, 0.2, 0.3, 0.4, 0.5]

        self.axesa.clear()
        self.axesa.set_xlim(-self.bsz / 8.0, self.bsz / 8.0)
        self.axesa.set_ylim(-self.bsz / 8.0, self.bsz / 8.0)
        self.axesa.set_xticks([-0.4, -0.2, 0.0, 0.2, 0.4])
        self.axesa.set_yticks([-0.4, -0.2, 0.0, 0.2, 0.4])
        self.axesa.contourf(self.xi1,
                            self.xi2,
                            self.sgals,
                            levels_imgs,
                            cmap=pl.cm.gray)
        self.axesa.contour(self.xi1,
                           self.xi2,
                           g_source,
                           levels,
                           colors=('deepskyblue'))
        self.axesa.contour(yi1, yi2, mua, 0, colors=('r'), linewidths=2.0)

        self.axesb.clear()
        # pl.xticks([-2.0, -1.0, 0.0, 1.0, 2.0])
        # pl.yticks([-2.0, -1.0, 0.0, 1.0, 2.0])
        self.axesb.set_xlim(-self.bsz / 2.0, self.bsz / 2.0)
        self.axesb.set_ylim(-self.bsz / 2.0, self.bsz / 2.0)
        self.axesb.contourf(self.xi1,
                            self.xi2,
                            self.lgals,
                            levels_imgs,
                            cmap=pl.cm.gray)
        self.axesb.contour(self.xi1,
                           self.xi2,
                           g_limage,
                           levels,
                           colors=('deepskyblue'))
        self.axesb.contour(self.xi1,
                           self.xi2,
                           mua,
                           colors=('r'),
                           linewidths=2.0)

        self.canvas.draw()

        self.slider_label_re.setText("Re: %.2f" % self.lpar[2])

        # print "Drag", self.lpar

    # @profile
    def create_main_frame(self):
        self.main_frame = QWidget()
        #self.main_frame.resize(800, 400)
        self.main_frame.setFixedSize(820, 700)

        self.dpi = 80
        self.fig = pl.figure(num=None,
                             figsize=(10, 5),
                             dpi=self.dpi,
                             facecolor='w',
                             edgecolor='k')
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self.main_frame)

        self.axesa = pl.axes([0.05, 0.1, 0.4, 0.8])
        self.axesb = pl.axes([0.55, 0.1, 0.4, 0.8])

        # Bind the 'pick' event for clicking on one of the bars
        #
        self.canvas.mpl_connect('pick_event', self.on_pick)

        # Create the navigation toolbar, tied to the canvas
        #
        self.mpl_toolbar = NavigationToolbar(self.canvas, self.main_frame)

        # Other GUI controls
        #
        self.textbox = QLineEdit()
        self.textbox.setMinimumWidth(200)
        self.textbox.editingFinished.connect(self.on_draw)

        self.cb_cosmo = QComboBox()
        self.cb_cosmo.addItems(
            ["Planck15", "WMP9", "Concordance", "Einstein-deSitter"])
        #self.cb_cosmo.currentIndexChanged.connect(self.selectionchange)

        self.cb_models = QComboBox()
        self.cb_models.addItems(["SIE", "NFW", "PIEMD"])
        #self.cb_models.currentIndexChanged.connect(self.selectionchange)

        self.cb_codes = QComboBox()
        self.cb_codes.addItems(
            ["Scipy", "Q-Lens", "Lensed", "LensTool", "Gravlens", "Glafic"])
        #self.cb.currentIndexChanged.connect(self.selectionchange)

        self.draw_button = QPushButton("&Optimize")
        #self.draw_button.clicked.connect(lambda: self.optmization_actions("lensed"))
        self.draw_button.clicked.connect(self.optimization_actions)

        #self.grid_cb = QCheckBox("Show &Grid")
        #self.grid_cb.setChecked(False)
        #self.grid_cb.stateChanged.connect(self.on_draw) #int

        self.slider_label_re = QLabel("Re = %.2f" % self.lpar[2])
        self.slider_re = QSlider(Qt.Horizontal)
        self.slider_re.setMinimumWidth(270)
        self.slider_re.setMaximumWidth(270)
        self.slider_re.setRange(1, nbins)
        self.slider_re.setValue(nbins / 2)
        self.slider_re.setTracking(True)
        #self.slider_re.setTickPosition(QSlider.TicksBothSides)
        self.slider_re.valueChanged.connect(self.on_draw)  #int

        slider_label_x1 = QLabel("Lens Position x1")
        self.slider_x1 = QSlider(Qt.Horizontal)
        self.slider_x1.setMinimumWidth(270)
        self.slider_x1.setMaximumWidth(270)
        self.slider_x1.setRange(1, nbins)
        self.slider_x1.setValue(nbins / 2)
        self.slider_x1.setTracking(True)
        #self.slider_x1.setTickPosition(QSlider.TicksBothSides)
        self.slider_x1.valueChanged.connect(self.on_draw)  #int

        slider_label_x2 = QLabel("Lens Position x2")
        self.slider_x2 = QSlider(Qt.Horizontal)
        self.slider_x2.setMinimumWidth(270)
        self.slider_x2.setMaximumWidth(270)
        self.slider_x2.setRange(1, nbins)
        self.slider_x2.setValue(nbins / 2)
        self.slider_x2.setTracking(True)
        #self.slider_x2.setTickPosition(QSlider.TicksBothSides)
        self.slider_x2.valueChanged.connect(self.on_draw)  #int

        slider_label_ql = QLabel("Ellipticity L")
        self.slider_ql = QSlider(Qt.Horizontal)
        self.slider_ql.setMinimumWidth(270)
        self.slider_ql.setMaximumWidth(270)
        self.slider_ql.setRange(1, nbins)
        self.slider_ql.setValue(nbins / 2)
        self.slider_ql.setTracking(True)
        #self.slider_ql.setTickPosition(QSlider.TicksBothSides)
        self.slider_ql.valueChanged.connect(self.on_draw)  #int

        slider_label_la = QLabel("Orintation L")
        self.slider_la = QSlider(Qt.Horizontal)
        self.slider_la.setMinimumWidth(270)
        self.slider_la.setMaximumWidth(270)
        self.slider_la.setRange(1, nbins)
        self.slider_la.setValue(nbins / 3)
        self.slider_la.setTracking(True)
        #self.slider_la.setTickPosition(QSlider.TicksBothSides)
        self.slider_la.valueChanged.connect(self.on_draw)  #int

        slider_label_rh = QLabel("Half-light Radius")
        self.slider_rh = QSlider(Qt.Horizontal)
        self.slider_rh.setMinimumWidth(270)
        self.slider_rh.setMaximumWidth(270)
        self.slider_rh.setRange(1, nbins)
        self.slider_rh.setValue(nbins / 2)
        self.slider_rh.setTracking(True)
        #self.slider_rh.setTickPosition(QSlider.TicksBothSides)
        self.slider_rh.valueChanged.connect(self.on_draw)  #int

        slider_label_y1 = QLabel("Source Position y1")
        self.slider_y1 = QSlider(Qt.Horizontal)
        self.slider_y1.setMinimumWidth(270)
        self.slider_y1.setMaximumWidth(270)
        self.slider_y1.setRange(1, nbins)
        self.slider_y1.setValue(nbins / 2)
        self.slider_y1.setTracking(True)
        #self.slider_y1.setTickPosition(QSlider.TicksBothSides)
        self.slider_y1.valueChanged.connect(self.on_draw)  #int

        slider_label_y2 = QLabel("Source Position y2")
        self.slider_y2 = QSlider(Qt.Horizontal)
        self.slider_y2.setMinimumWidth(270)
        self.slider_y2.setMaximumWidth(270)
        self.slider_y2.setRange(1, nbins)
        self.slider_y2.setValue(nbins / 2)
        self.slider_y2.setTracking(True)
        #self.slider_y2.setTickPosition(QSlider.TicksBothSides)
        self.slider_y2.valueChanged.connect(self.on_draw)  #int

        slider_label_qs = QLabel("Ellipticity S")
        self.slider_qs = QSlider(Qt.Horizontal)
        self.slider_qs.setMinimumWidth(270)
        self.slider_qs.setMaximumWidth(270)
        self.slider_qs.setRange(1, nbins)
        self.slider_qs.setValue(nbins / 2)
        self.slider_qs.setTracking(True)
        #self.slider_qs.setTickPosition(QSlider.TicksBothSides)
        self.slider_qs.valueChanged.connect(self.on_draw)  #int

        slider_label_sa = QLabel("Orintation S")
        self.slider_sa = QSlider(Qt.Horizontal)
        self.slider_sa.setMinimumWidth(270)
        self.slider_sa.setMaximumWidth(270)
        self.slider_sa.setRange(1, nbins)
        self.slider_sa.setValue(nbins / 3)
        self.slider_sa.setTracking(True)
        #self.slider_sa.setTickPosition(QSlider.TicksBothSides)
        self.slider_sa.valueChanged.connect(self.on_draw)  #int

        #
        # Layout with box sizers
        #
        hbox = QHBoxLayout()

        for w in [
                self.textbox, self.cb_cosmo, self.cb_models, self.cb_codes,
                self.draw_button
        ]:
            hbox.addWidget(w)
            hbox.setAlignment(w, Qt.AlignVCenter)

        vbox = QVBoxLayout()
        vbox.addWidget(self.mpl_toolbar)
        vbox.addWidget(self.canvas)

        hbox_s1 = QHBoxLayout()
        for w in [
                self.slider_label_re, self.slider_re, slider_label_rh,
                self.slider_rh
        ]:
            hbox_s1.addWidget(w)
            hbox_s1.setAlignment(w, Qt.AlignLeft)

        hbox_s2 = QHBoxLayout()
        for w in [
                slider_label_x1, self.slider_x1, slider_label_y1,
                self.slider_y1
        ]:
            hbox_s2.addWidget(w)
            hbox_s2.setAlignment(w, Qt.AlignLeft)

        hbox_s3 = QHBoxLayout()
        for w in [
                slider_label_x2, self.slider_x2, slider_label_y2,
                self.slider_y2
        ]:
            hbox_s3.addWidget(w)
            hbox_s3.setAlignment(w, Qt.AlignLeft)

        hbox_s4 = QHBoxLayout()
        for w in [
                slider_label_ql, self.slider_ql, slider_label_qs,
                self.slider_qs
        ]:
            hbox_s4.addWidget(w)
            hbox_s4.setAlignment(w, Qt.AlignLeft)

        hbox_s5 = QHBoxLayout()
        for w in [
                slider_label_la, self.slider_la, slider_label_sa,
                self.slider_sa
        ]:
            hbox_s5.addWidget(w)
            hbox_s5.setAlignment(w, Qt.AlignLeft)

        vbox.addLayout(hbox)
        vbox.addLayout(hbox_s1)
        vbox.addLayout(hbox_s2)
        vbox.addLayout(hbox_s3)
        vbox.addLayout(hbox_s4)
        vbox.addLayout(hbox_s5)

        self.main_frame.setLayout(vbox)
        self.setCentralWidget(self.main_frame)

    def optimization_actions(self):
        print "Optimizing..."
        lpar_new, spar_new = ff.optimize_pars(self.xi1, self.xi2,
                                              self.lgals.ravel(), self.lpar,
                                              self.spar)

        g_limage, g_source, mua, yi1, yi2 = ll.lensed_images(
            self.xi1, self.xi2, lpar_new, spar_new)
        print "Done."

        self.slider_re.setValue(round(lpar_new[2] / 2.0 * nbins))
        self.slider_x1.setValue(
            round((lpar_new[0] + self.bsz / 2.0 - self.bsz / nbins / 2.0) /
                  self.bsz * nbins))
        self.slider_x2.setValue(
            round((lpar_new[1] + self.bsz / 2.0 - self.bsz / nbins / 2.0) /
                  self.bsz * nbins))
        self.slider_ql.setValue(round(lpar_new[4] * nbins))
        self.slider_la.setValue(round(lpar_new[5] / 360.0 * nbins))

        self.slider_rh.setValue(round(spar_new[2] / 0.5 * nbins))
        self.slider_y1.setValue(
            round((spar_new[0] + self.bsz / 8.0 - self.bsz / nbins / 8.0) /
                  (self.bsz / 4.0) * nbins))
        self.slider_y2.setValue(
            round((spar_new[1] + self.bsz / 8.0 - self.bsz / nbins / 8.0) /
                  (self.bsz / 4.0) * nbins))
        self.slider_qs.setValue(round(spar_new[4] * nbins))
        self.slider_sa.setValue(round(spar_new[5] / 360.0 * nbins))

        levels = [
            0.5,
        ]
        levels_imgs = [0.0, 0.08, 0.1, 0.2, 0.3, 0.4, 0.5]
        self.axesa.clear()
        # pl.xticks([-2.0, 1.0, 0.0, 1.0, 2.0])
        # pl.yticks([-2.0, 1.0, 0.0, 1.0, 2.0])
        self.axesa.set_xlim(-self.bsz / 8.0, self.bsz / 8.0)
        self.axesa.set_ylim(-self.bsz / 8.0, self.bsz / 8.0)
        self.axesa.contourf(self.xi1,
                            self.xi2,
                            self.sgals,
                            levels_imgs,
                            cmap=pl.cm.gray)
        self.axesa.contour(self.xi1,
                           self.xi2,
                           g_source,
                           levels,
                           colors=('deepskyblue'))
        self.axesa.contour(yi1, yi2, mua, 0, colors=('g'), linewidths=2.0)

        self.axesb.clear()
        # pl.xticks([-0.2,-0.1,0.0,0.1,0.2])
        # pl.yticks([-0.2,-0.1,0.0,0.1,0.2])
        self.axesb.set_xlim(-self.bsz / 2.0, self.bsz / 2.0)
        self.axesb.set_ylim(-self.bsz / 2.0, self.bsz / 2.0)
        self.axesb.contourf(self.xi1,
                            self.xi2,
                            self.lgals,
                            levels_imgs,
                            cmap=pl.cm.gray)
        self.axesb.contour(self.xi1,
                           self.xi2,
                           g_limage,
                           levels,
                           colors=('deepskyblue'))
        self.axesb.contour(self.xi1,
                           self.xi2,
                           mua,
                           colors=('r'),
                           linewidths=2.0)

        self.canvas.draw()

        print "opt----", spar_new

    def create_status_bar(self):
        self.status_text = QLabel("This is a statusbar")
        self.statusBar().addWidget(self.status_text, 1)

    def create_menu(self):
        self.file_menu = self.menuBar().addMenu("&File")

        load_file_action = self.create_action("&Save plot",
                                              shortcut="Ctrl+S",
                                              slot=self.save_plot,
                                              tip="Save the plot")
        quit_action = self.create_action("&Quit",
                                         slot=self.close,
                                         shortcut="Ctrl+Q",
                                         tip="Close the application")

        self.add_actions(self.file_menu, (load_file_action, None, quit_action))

        self.help_menu = self.menuBar().addMenu("&Help")
        about_action = self.create_action("&About",
                                          shortcut='F1',
                                          slot=self.on_about,
                                          tip='About the demo')

        self.add_actions(self.help_menu, (about_action, ))

    def add_actions(self, target, actions):
        for action in actions:
            if action is None:
                target.addSeparator()
            else:
                target.addAction(action)

    def create_action(self,
                      text,
                      slot=None,
                      shortcut=None,
                      icon=None,
                      tip=None,
                      checkable=False,
                      signal="triggered()"):
        action = QAction(text, self)
        if icon is not None:
            action.setIcon(QIcon(":/%s.png" % icon))
        if shortcut is not None:
            action.setShortcut(shortcut)
        if tip is not None:
            action.setToolTip(tip)
            action.setStatusTip(tip)
        if slot is not None:
            action.triggered.connect(slot)
        if checkable:
            action.setCheckable(True)
        return action
Beispiel #35
0
class PfGui(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui = UiMainWindow(self)
        self.ui.push_button.setEnabled(False)

        self.results = {
            'peak_intensity_matrix': None,
            'index': None,
            'square_instances': None
        }
        self.instance = Reader.TwoDScan()
        self.selected_square = []
        self.cid_press = None
        self.cid_release = None
        self.cid_motion = None

        os.chdir(os.path.dirname(sys.argv[0]))
        self.gui_cfg = configparser.ConfigParser()
        self.gui_cfg.read('GUI.cfg')

        self.ui.actionOpen_2.triggered.connect(self.open_file)
        self.ui.actionSave.triggered.connect(self.save_image)

        self.figure = plt.figure()
        self.figure.set_size_inches((30, 6))
        self.canvas = FigureCanvas(self.figure)
        self.ui.verticalLayout.addWidget(self.canvas)
        self.connect_canvas()

        self.ui.push_button.clicked.connect(self.automatically_detect_peak)

    def open_file(self):

        self.results = {
            'peak_intensity_matrix': None,
            'index': None,
            'square_instances': None
        }

        dir_item = self.gui_cfg.get('DEFAULT', 'directory') or '\home'

        raw_file_name = QtWidgets.QFileDialog.getOpenFileName(
            self, 'Open file', dir_item, "RAW files (*.raw)")
        raw_file_name = str(raw_file_name[0])

        if raw_file_name:
            raw_instance = Reader.RawFile(raw_file_name).read_data()
            self.figure.clear()
            raw_instance.plot(is_show=0, is_save=0)
            self.canvas.draw()
            self.ui.push_button.setEnabled(True)
            self.instance = raw_instance
            self.gui_cfg.set('DEFAULT', 'directory',
                             os.path.dirname(raw_file_name))
        else:
            pass

    def save_image(self):
        supported_file_dict = self.canvas.get_supported_filetypes()
        supported_file_list = [
            "{0} (*.{1})".format(supported_file_dict[i], i)
            for i in supported_file_dict
        ]
        supported_file_str = ";;".join(supported_file_list)

        dir_item = self.gui_cfg.get('DEFAULT', 'directory') or '\home'

        image_file_name = QtWidgets.QFileDialog.getSaveFileName(
            self, 'Open file', dir_item, supported_file_str)
        image_file_name = str(image_file_name[0])

        if image_file_name:
            self.figure.savefig(image_file_name, bbox_inches='tight')
        else:
            return

    def save_config(self):
        script_path = os.path.dirname(sys.argv[0])
        with open(os.path.join(script_path, 'GUI.cfg'), 'w') as config_file:
            self.gui_cfg.write(config_file)

    def automatically_detect_peak(self):
        if self.results['square_instances']:
            for i in self.results['square_instances']:
                i.remove()

        results_dict = self.instance.plot_square(is_show=0, is_save=0)
        self.results = results_dict
        self.canvas.draw()

        v_fration = self.instance.mt_intensity_to_fraction(results_dict)
        data_dict = {
            'Peak Intensity': results_dict['peak_intensity_matrix'],
            'Volume Fraction': v_fration
        }
        self.instance.print_result_csv(self.instance.scan_dict['sample'],
                                       data_dict)
        self.update_fraction_list(v_fration)

        bg_err = (self.instance.get_bg_int() /
                  (self.instance.get_bg_int() +
                   results_dict['peak_intensity_matrix'].mean()))
        self.ui.statusbar.showMessage("{0}%".format(bg_err * 100))

    def connect_canvas(self):
        self.cid_press = self.canvas.mpl_connect('button_press_event',
                                                 self.on_press)
        self.cid_release = self.canvas.mpl_connect('button_release_event',
                                                   self.on_release)
        self.cid_motion = self.canvas.mpl_connect('motion_notify_event',
                                                  self.on_motion)

    def on_press(self, event):
        ax_list = self.figure.axes
        if self.results['square_instances'] is None:
            return
        if event.inaxes != ax_list[0]:
            return
        for square in self.results['square_instances']:
            if [event.xdata, event.ydata] in square:
                self.selected_square.append(square)

    def on_motion(self, event):
        if not self.selected_square:
            return
        if event.inaxes != self.figure.axes[0]:
            return
        [init_mouse_y, init_mouse_x] = self.selected_square[0].cr_list
        for square in self.selected_square:
            dy = event.xdata - init_mouse_x + 30
            dx = event.ydata - init_mouse_y
            square.move((dx, dy))

        self.canvas.draw()

    def update_fraction_list(self, results):
        text_label_list = [
            self.ui.mt_a_value, self.ui.mt_d_value, self.ui.mt_c_value,
            self.ui.mt_b_value
        ]
        for (i, j) in zip(text_label_list, results):
            i.setText(str(j))

    def on_release(self, event):
        if self.results['square_instances'] is None:
            return
        self.selected_square = []

        outer_index_list = [
            i.cr_list for i in self.results['square_instances'][:4]
        ]
        results_dict = self.instance.plot_square(
            is_show=0, is_save=0, is_plot=0, outer_index_list=outer_index_list)
        results = self.instance.mt_intensity_to_fraction(results_dict)
        data_dict = {
            'Peak Intensity': results_dict['peak_intensity_matrix'],
            'Volume Fraction': results
        }
        self.instance.print_result_csv(self.instance.scan_dict['sample'],
                                       data_dict)
        self.update_fraction_list(results)

    def disconnect(self):
        self.canvas.mpl_disconnect(self.cid_press)
        self.canvas.mpl_disconnect(self.cid_release)
        self.canvas.mpl_disconnect(self.cid_motion)
Beispiel #36
0
class LogTab(QWidget):
    def __init__(self):
        super(LogTab, self).__init__()

        # Class variables.
        # self.graphXValueList = []
        # self.graphYValueList = []
        # self.counter = 0

        self.currentlySelectedRoastLog = {}
        self.currentlySelectedRoastLogPath = ""

        # Create the tab ui.
        self.create_ui()

    def create_ui(self):
        # Create the main layout for the roast tab.
        self.layout = QGridLayout()

        # Create log browser.
        self.create_log_browser()
        self.layout.addWidget(self.logBrowser, 0, 0)

        # Create graph widget.
        self.create_graph()
        self.layout.addWidget(self.graphWidget, 0, 0)
        self.layout.setColumnStretch(0, 1)

        # Create right pane.
        # self.rightPane = self.create_right_pane()
        # self.layout.addLayout(self.rightPane, 0, 1)

        # Set main layout for widget.
        self.setLayout(self.layout)

    def create_log_browser(self):
        """Creates the side panel to browse all the files in the log folder."""
        # Creates model with all information about the files in ./recipes
        self.model = LogModel()
        self.model.setRootPath(os.path.expanduser('~/Documents/Roastero/log/'))

        # Create a TreeView to view the information from the model
        self.logBrowser = QTreeView()
        self.logBrowser.setModel(self.model)
        self.logBrowser.setRootIndex(self.model.index(os.path.expanduser('~/Documents/Roastero/log/')))
        self.logBrowser.setFocusPolicy(Qt.NoFocus)
        self.logBrowser.header().close()

        self.logBrowser.setAnimated(True)
        self.logBrowser.setIndentation(0)

        # Hides all the unecessary columns created by the model
        self.logBrowser.setColumnHidden(0, True)
        self.logBrowser.setColumnHidden(1, True)
        self.logBrowser.setColumnHidden(2, True)
        self.logBrowser.setColumnHidden(3, True)

        self.logBrowser.clicked.connect(self.on_logBrowser_clicked)

    def create_graph(self):
        # Create the graph widget.
        self.graphWidget = QWidget(self)
        self.graphWidget.setObjectName("graph")

        # Style attributes of matplotlib.
        plt.rcParams['lines.linewidth'] = 3
        plt.rcParams['lines.color'] = '#2a2a2a'
        plt.rcParams['font.size'] = 10.

        self.graphFigure = plt.figure(facecolor='#444952')
        self.graphCanvas = FigureCanvas(self.graphFigure)

        # Add graph widgets to layout for graph.
        graphVerticalBox = QVBoxLayout()
        graphVerticalBox.addWidget(self.graphCanvas)
        self.graphWidget.setLayout(graphVerticalBox)

        # # Animate the the graph with new data
        # animateGraph = animation.FuncAnimation(self.graphFigure,
        #     self.graph_draw, interval=1000)

    def graph_draw(self, graphXValueList = None, graphYValueList = None):
        self.graphFigure.clear()

        self.graphAxes = self.graphFigure.add_subplot(111)
        self.graphAxes.plot_date(graphXValueList, graphYValueList,
            '#8ab71b')

        # Add formatting to the graphs.
        self.graphAxes.set_ylabel('TEMPERATURE (°F)')
        self.graphAxes.set_xlabel('TIME')
        self.graphFigure.subplots_adjust(bottom=0.2)

        ax = self.graphAxes.get_axes()
        ax.xaxis.set_major_formatter(DateFormatter('%M:%S'))
        ax.set_axis_bgcolor('#23252a')

        self.graphCanvas.draw()

    def on_logBrowser_clicked(self, index):
        """This method is used when a log is selected in the left column."""
        indexItem = self.model.index(index.row(), 0, index.parent())

        self.selectedFilePath = self.model.filePath(indexItem)

        # Allow single click expanding of folders
        if os.path.isdir(self.selectedFilePath):
            if self.logBrowser.isExpanded(indexItem):
                self.logBrowser.collapse(indexItem)
            else:
                self.logBrowser.expand(indexItem)
        # Handles when a file is clicked
        else:
            # Load roast log information from file
            self.load_roast_log_file(self.selectedFilePath)

    def load_roast_log_file(self, filePath):
        """Used to load file from a path into selected roast log object."""
        with open(filePath) as json_data:
            roastLogObject = json.load(json_data)
        self.currentlySelectedRoastLog = roastLogObject
        self.currentlySelectedRoastLogPath = filePath
Beispiel #37
0
class Window(QtWidgets.QDialog):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)
        self.runStatus = False
        self.setGeometry(100, 100, 1200, 700)
        self.setFixedSize(1200, 700)
        self.setWindowTitle('1D Forward Modeling Magnetotelluric')
        self.setWindowIcon(QtGui.QIcon('../images/icon.png'))

        self.figure = Figure()
        self.canvas = FigureCanvas(self.figure)
        self.toolbar = NavigationToolbar(self.canvas, self)

        self.buttonPlot = QtWidgets.QPushButton('Run')
        self.buttonPlot.clicked.connect(self.get_data)

        self.buttonAbout = QtWidgets.QPushButton('About')
        self.buttonAbout.clicked.connect(self.form_about)

        self.buttonSModel = QtWidgets.QPushButton('Save Model')
        self.buttonSModel.clicked.connect(self.save_model)

        self.buttonSData = QtWidgets.QPushButton('Save Data')
        self.buttonSData.clicked.connect(self.save_data)

        textMaxPeriode = QtWidgets.QLabel('Maximum Period:')
        textNumDec = QtWidgets.QLabel('Number of Decade:')
        textPerDec = QtWidgets.QLabel('Periode per Decade:')
        self.lineEditMaxPeriode = QtWidgets.QLineEdit('1000', self)
        self.lineEditNumDec = QtWidgets.QLineEdit('6', self)
        self.lineEditPerDec = QtWidgets.QLineEdit('10', self)

        textRes = QtWidgets.QLabel('Resistivity:')
        textThi = QtWidgets.QLabel('Thickness:')
        self.lineEditRes = QtWidgets.QLineEdit('100, 10, 1000', self)
        self.lineEditThi = QtWidgets.QLineEdit('1000, 2000', self)

        horizontalLayout1 = QtWidgets.QHBoxLayout()
        horizontalLayout1.addWidget(textMaxPeriode)
        horizontalLayout1.addWidget(self.lineEditMaxPeriode)
        horizontalLayout1.addWidget(textNumDec)
        horizontalLayout1.addWidget(self.lineEditNumDec)
        horizontalLayout1.addWidget(textPerDec)
        horizontalLayout1.addWidget(self.lineEditPerDec)

        horizontalLayout2 = QtWidgets.QHBoxLayout()
        horizontalLayout2.addWidget(textRes)
        horizontalLayout2.addWidget(self.lineEditRes)
        horizontalLayout2.addWidget(textThi)
        horizontalLayout2.addWidget(self.lineEditThi)

        horizontalLayout3 = QtWidgets.QHBoxLayout()
        horizontalLayout3.addWidget(self.buttonPlot)
        horizontalLayout3.addWidget(self.buttonSModel)
        horizontalLayout3.addWidget(self.buttonSData)
        horizontalLayout3.addWidget(self.buttonAbout)

        verticalLayout = QtWidgets.QVBoxLayout()
        verticalLayout.addLayout(horizontalLayout1)
        verticalLayout.addLayout(horizontalLayout2)
        verticalLayout.addWidget(self.toolbar)
        verticalLayout.addWidget(self.canvas)
        verticalLayout.addLayout(horizontalLayout3)
        self.setLayout(verticalLayout)

    def form_about(self):
        QtWidgets.QMessageBox.information(
            self, '1DForModMT',
            '1D Forward Modeling Magnetotelluric is created by:'
            '\n'
            '\nEvi Muharoroh \tUnila \t\[email protected]'
            '\nArif Darmawan \tElnusa \t\[email protected]'
            '\n              \t\tRiflab \t\[email protected]'
            '\n'
            '\nThis is free and opensource software under GNU General Public Licensed.'
            '\nUse at your own risk but enjoy if it works for you'
            '\nOther softwares can be downloaded at https://github.com/riflab/'
            '\n'
            '\nVersion 1.0_20171121'
            '\nDate: 21 November 2017'
            '\n'
            '\nReference:'
            '\nGrandis, H. (1999). An alternative algorithm for one-dimensional magnetotelluric response calculation. Computer & Geoscienes 25 (1999) 199-125. ',
            QtWidgets.QMessageBox.Ok)

    def get_data(self):
        self.runStatus = True
        # get input ----------------------------------------------------------
        # min_freq = 1/ float(self.lineEditMaxPeriode.text())

        try:
            self.min_freq = 1 / float(self.lineEditMaxPeriode.text())
        except ValueError:
            self.runStatus = False
            QtWidgets.QMessageBox.warning(
                self, "Warning", "%s" %
                ('Wrong input!.\nMaximum period must be integer or float'))

        try:
            self.total_dec = int(self.lineEditNumDec.text())
        except ValueError:
            self.runStatus = False
            QtWidgets.QMessageBox.warning(
                self, "Warning",
                "%s" % ('Wrong input!.\nNumber of decade must be integer'))

        try:
            self.freq_per_dec = int(self.lineEditPerDec.text())
        except ValueError:
            self.runStatus = False
            QtWidgets.QMessageBox.warning(
                self, "Warning",
                "%s" % ('Wrong input!.\nFrequency per decade must be integer'))

        try:
            res = (self.lineEditRes.text()).split(',')
            self.ress = []
            for i in range(0, len(res)):
                self.ress.append(float(res[i]))
        except ValueError:
            self.runStatus = False
            QtWidgets.QMessageBox.warning(
                self, "Warning",
                "%s" % ('Wrong input!.\nResistivity must be integer or float'))

        try:
            thi = (self.lineEditThi.text()).split(',')
            self.thii = []
            for i in range(0, len(thi)):
                self.thii.append(float(thi[i]))
        except ValueError:
            self.runStatus = False
            QtWidgets.QMessageBox.warning(
                self, "Warning",
                "%s" % ('Wrong input!.\nThickness must be integer or float'))

        self.compute()

    def compute(self):
        # compute periode ----------------------------------------------------------
        nfreq = self.total_dec * self.freq_per_dec + 1
        frac = np.exp(np.log(10) / self.freq_per_dec)

        freq = []
        freq.append(self.min_freq)

        for i in range(1, nfreq):
            freq.append(freq[i - 1] * frac)

        self.per = []
        nper = len(freq)
        for i in range(0, nper):
            self.per.append(1 / freq[i])

        # compute depth ----------------------------------------------------------
        self.depth = []
        self.depth.append(1.0)
        a = 0
        for i in range(len(self.thii)):
            a += self.thii[i]
            self.depth.append(a)
            self.depth.append(a)
        self.depth.append(a * 1000000)  # 1000000 denotes infinity

        # compute ress
        self.resss = []
        for i in range(len(self.ress)):
            self.resss.append(self.ress[i])
            self.resss.append(self.ress[i])

        # compute forward 1D ----------------------------------------------------------
        self.rho, self.phas = FFMT1D.ffmt1d(self.ress, self.thii, self.per)

        self.plot()

    def plot(self):

        # create an axis
        ax1 = self.figure.add_subplot(1, 4, 1)
        ax2 = self.figure.add_subplot(2, 4, (2, 4))
        ax3 = self.figure.add_subplot(2, 4, (6, 8))

        # discards the old graph
        ax1.clear()
        ax2.clear()
        ax3.clear()

        # plot data
        ax1.loglog(self.resss, self.depth, '-', linewidth=0.7)
        ax1.set_xlabel('Resistivity (ohm meter)', fontsize=8)
        ax1.set_ylabel('Depth (m)', fontsize=8)
        ax1.set_title('Model', fontsize=8)
        ax1.set_ylim(1, max(self.depth) / 100000)
        ax1.invert_yaxis()

        ax2.loglog(self.per, self.rho, '*-', linewidth=0.7, markersize=4)
        ax2.set_ylim(1, 1000)
        ax2.set_xlabel('Period (s)', fontsize=8)
        ax2.set_ylabel('Ohm meter', fontsize=8)
        ax2.set_title('Apparent Resistivity', fontsize=8)

        ax3.semilogx(self.per, self.phas, '*-', linewidth=0.7, markersize=4)
        ax3.set_ylim(0, 90)
        ax3.set_xlabel('Period (s)', fontsize=8)
        ax3.set_ylabel('Degree', fontsize=8)
        ax3.set_title('Phase', fontsize=8)

        self.figure.tight_layout()
        self.canvas.draw()

    def save_model(self):
        if self.runStatus == True:

            fileModel = QtWidgets.QFileDialog.getSaveFileName(
                self, 'Save Model File')

            text_file = open(fileModel, "w")
            text_file.write('%-15s %s\n' % ('Depth (m)', 'Resistivity'))

            for i in range(len(self.resss) - 1):
                text_file.write('%-15s %s\n' % (self.depth[i], self.resss[i]))
            text_file.write('%-15s %s\n' %
                            ('infinity', self.resss[len(self.resss) - 1]))

            text_file.close()

            QtWidgets.QMessageBox.information(
                self, "Success", "%s" % ('Write model file, done!'))
        else:
            QtWidgets.QMessageBox.warning(
                self, "Warning",
                "%s" % ('You must run 1D Forward before save the Model'))

    def save_data(self):
        if self.runStatus == True:

            fileData = QtWidgets.QFileDialog.getSaveFileName(
                self, 'Save Data File')

            text_fileD = open(fileData, "w")
            text_fileD.write('%-15s %-15s %-15s\n' %
                             ('Period (s)', 'App. Res.', 'Phase'))

            for i in range(len(self.per)):
                text_fileD.write('%-15.2f %-15.2f %-15.2f\n' %
                                 (self.per[i], self.rho[i], self.phas[i]))

            text_fileD.close()

            QtWidgets.QMessageBox.information(
                self, "Success", "%s" % ('Write model file, done!'))
        else:
            QtWidgets.QMessageBox.warning(
                self, "Warning",
                "%s" % ('You must run 1D Forward before save the Data'))
Beispiel #38
0
class Window(QDialog):
    def __init__(self, params_object, library_object, group, parent=None):
        QDialog.__init__(self, parent)
        self.params = params_object
        self.library = library_object
        self.group = group
        matplotlib.projections.register_projection(My_Axes)
        self.region_colors = {0:'gray', 1:'red', 2:'green', 3:'orange', 4:'teal', 5:'pink',
                              6:'cyan', 7:'magenta', 8:'gold'}
        if self.group == 'ALL':
            self.plural_group = "s"
        else:
            self.plural_group = ""
        self.setWindowTitle("NMRmix: Peaks Histogram for %s Group%s" % (self.group, self.plural_group))
        self.scale = 1.05
        self.setAttribute(Qt.WA_DeleteOnClose, True)
        self.createMainFrame()

    def createMainFrame(self):
        self.fig = plt.gcf()
        self.fig.patch.set_facecolor('white')
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self)
        self.canvas.setFocusPolicy(Qt.StrongFocus)
        self.canvas.setFocus()
        self.canvas.setMinimumHeight(100)
        self.canvas.setMinimumWidth(100)

        self.mpl_toolbar = NavigationToolbar2(self.canvas, self)
        self.mpl_toolbar.hide()
        self.mpl_toolbar.pan()
        self.canvas.mpl_connect('scroll_event', self.zooming)
        ins = "Left-click+drag to pan x-axis / Right-click+drag to zoom x-axis"
        self.instructionLabel = QLabel(ins)
        self.instructionLabel.setStyleSheet('QLabel{qproperty-alignment: AlignCenter; font-size: 12px;}')

        self.showignoredregionsCheckBox = QCheckBox("Show Ignored Regions")
        self.showignoredregionsCheckBox.setChecked(True)
        self.showignoredregionsCheckBox.setToolTip("Tooltip") # TODO: Tooltip
        self.showignoredregionsCheckBox.stateChanged.connect(self.handleIgnored)
        self.closeButton = QPushButton("Close")
        self.closeButton.setStyleSheet("QPushButton{color: red; font-weight: bold;}")
        self.closeButton.clicked.connect(self.closeEvent)
        self.saveButton = QPushButton("Save")
        self.saveButton.setStyleSheet("QPushButton{color: green; font-weight: bold;}")
        self.saveButton.clicked.connect(self.saveResults)
        self.resetButton = QPushButton("Reset")
        self.resetButton.setStyleSheet("QPushButton{color: blue; font-weight: bold;}")
        self.resetButton.clicked.connect(self.resetGraph)
        self.calculateAllHistogram()
        self.calculateIntenseHistogram()
        self.drawIgnoredRegions()
        winLayout = QVBoxLayout(self)
        winLayout.addWidget(self.canvas)
        winLayout.addWidget(self.instructionLabel)
        winLayout.addWidget(self.showignoredregionsCheckBox)
        buttonLayout = QHBoxLayout()
        buttonLayout.addWidget(self.closeButton)
        buttonLayout.addWidget(self.resetButton)
        buttonLayout.addWidget(self.saveButton)
        winLayout.addLayout(buttonLayout)
        winLayout.setAlignment(self.showignoredregionsCheckBox, Qt.AlignCenter)
        self.fig.tight_layout(pad=3)
        self.canvas.draw()

    def calculateAllHistogram(self):
        self.ax1 = self.fig.add_subplot(211, projection="My_Axes")
        self.ax1.set_title("Peaks Histogram for %s Group%s" % (self.group, self.plural_group), fontweight='bold')
        self.ax1.set_xlabel("Chemical Shift (ppm)", fontweight='bold')
        self.ax1.set_ylabel("Number of Peaks", fontweight='bold')
        data = list(self.library.stats[self.group]['Peaklist'])
        y, binEdges = np.histogram(data, bins=np.arange(-1, 12, 0.02))
        bincenters = 0.5 * (binEdges[1:] + binEdges[:-1])
        self.ax1.set_xlim(self.params.shift_range[self.params.nuclei])
        self.upper_ylim_all = max(y)+(math.ceil(max(y)*0.05))
        self.ax1.set_ylim([0, self.upper_ylim_all])
        self.ax1.plot(bincenters, y, '-', color='blue')

    def calculateIntenseHistogram(self):
        self.ax2 = self.fig.add_subplot(212, sharex=self.ax1, projection="My_Axes")
        self.ax2.set_title("Intense Peaks Histogram for %s Group%s" % (self.group, self.plural_group),
                           fontweight='bold')
        self.ax2.set_xlabel("Chemical Shift (ppm)", fontweight='bold')
        self.ax2.set_ylabel("Number of Peaks", fontweight='bold')
        data = list(self.library.stats[self.group]['Intense Peaklist'])
        y, binEdges = np.histogram(data, bins=np.arange(-1, 12, 0.02))
        bincenters = 0.5 * (binEdges[1:] + binEdges[:-1])
        self.ax2.set_xlim([12, -1])
        self.upper_ylim_intense = max(y)+(math.ceil(max(y)*0.05))
        self.ax2.set_ylim([0, self.upper_ylim_intense])
        self.ax2.plot(bincenters, y, '-', color='purple')

    def resetGraph(self):
        self.mpl_toolbar.home()

    def drawIgnoredRegions(self):
        groups = ['ALL']
        if self.group != 'ALL':
            groups.append(self.group)
        for region in self.library.ignored_regions:
            group = self.library.ignored_regions[region][2]
            if self.group == 'ALL':
                if group not in groups:
                    groups.append(group)
        for region in self.library.ignored_regions:
            lower_bound = self.library.ignored_regions[region][0]
            upper_bound = self.library.ignored_regions[region][1]
            group = self.library.ignored_regions[region][2]
            if group in groups:
                color = self.region_colors[groups.index(group)]
                bar_width = abs(upper_bound - lower_bound)
                bar_center = (lower_bound + upper_bound) / 2
                self.ax1.bar(bar_center, self.upper_ylim_all, width=bar_width, color=color, align='center', edgecolor=color,
                             linewidth=1, alpha=0.4)
                self.ax2.bar(bar_center, self.upper_ylim_intense, width=bar_width, color=color, align='center',
                             edgecolor=color, linewidth=1, alpha=0.4)
            else:
                continue

    def handleIgnored(self):
        if self.showignoredregionsCheckBox.isChecked():
            self.fig.clear()
            self.calculateAllHistogram()
            self.calculateIntenseHistogram()
            self.drawIgnoredRegions()
            self.canvas.draw()
        else:
            self.fig.clear()
            self.calculateAllHistogram()
            self.calculateIntenseHistogram()
            self.canvas.draw()

    def zooming(self, event):
        cur_ylim1 = self.ax1.get_ylim()
        cur_ylim2 = self.ax2.get_ylim()
        cur_yrange1 = (cur_ylim1[1] - cur_ylim1[0])
        cur_yrange2 = (cur_ylim2[1] - cur_ylim2[0])
        if event.button == 'up':
            scale_factor = self.scale
        elif event.button == 'down':
            scale_factor = 1/self.scale
        else:
            scale_factor = 1

        self.ax1.set_ylim([0, (cur_yrange1*scale_factor)])
        self.ax2.set_ylim([0, (cur_yrange2*scale_factor)])
        self.canvas.draw()

    def saveResults(self):
        filename = "peakstats.png"
        filepath = os.path.join(self.params.work_dir, filename)
        filestype = "static (*.png *.jpg *.svg)"
        fileObj = QFileDialog.getSaveFileName(self, caption="Save Peak Stats Plot", directory=filepath, filter=filestype)
        if fileObj[0]:
            self.fig.set_size_inches(12, 8)
            plt.savefig(fileObj[0], dpi=200)

    def closeEvent(self, event=False):
        self.fig.clear()
        QDialog.reject(self)
Beispiel #39
0
class App(QMainWindow):
    def __init__(self):
        super(App, self).__init__()

        self.title = 'Histogram Equalization'

        self.inputLoaded = False
        self.targetLoaded = False

        self.initUI()

    def initUI(self):
        # Write GUI initialization code
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('File')

        self.groupBox1 = QGroupBox(self)
        self.groupBox2 = QGroupBox(self)
        self.groupBox3 = QGroupBox(self)

        self.groupBox1.setTitle("Input")
        self.groupBox1.resize(500, 1000)
        self.groupBox1.move(100, 50)

        self.groupBox2.setTitle("Target")
        self.groupBox2.resize(500, 1000)
        self.groupBox2.move(700, 50)

        self.groupBox3.setTitle("Output")
        self.groupBox3.resize(500, 1000)
        self.groupBox3.move(1300, 50)

        mainLayout = QHBoxLayout(self)
        mainLayout.addStretch(1)

        mainLayout.addWidget(self.groupBox1)
        mainLayout.addWidget(self.groupBox2)
        mainLayout.addWidget(self.groupBox3)

        impAct1 = QAction('Open Input', self)
        impAct1.triggered.connect(self.openInputImage)
        impAct2 = QAction('Open Target', self)
        impAct2.triggered.connect(self.openTargetImage)
        impAct3 = QAction('Exit', self)
        impAct3.setShortcut('Ctrl+Q')
        impAct3.triggered.connect(self.quitProgram)

        fileMenu.addAction(impAct1)
        fileMenu.addAction(impAct2)
        fileMenu.addAction(impAct3)

        eqAct = QAction('Equalize Histogram', self)
        eqAct.triggered.connect(self.histogramButtonClicked)

        self.toolbar = self.addToolBar('Equalize Histogram')
        self.toolbar.addAction(eqAct)

        self.setWindowTitle('Histogram Equalization')

        self.setLayout(mainLayout)

        self.show()

    def openInputImage(self):
        # This function is called when the user clicks File->Input Image.

        #The QLabel where we can display an Image
        self.label = QLabel(self)
        self.boxLayout = QVBoxLayout(self.groupBox1)
        self.boxLayout.addWidget(self.label)

        self.imagePath, _ = QFileDialog.getOpenFileName(self, 'OpenFile')
        self.pixmap = QPixmap(self.imagePath)
        self.label.setPixmap(self.pixmap)

        #Histogram of image
        self.histimage = cv2.imread(self.imagePath)
        self.hist1 = histogram(self.histimage)

        self.canvas0 = FigureCanvas(Figure(figsize=(5, 3)))
        self.canvas1 = FigureCanvas(Figure(figsize=(5, 3)))
        self.canvas2 = FigureCanvas(Figure(figsize=(5, 3)))

        self.boxLayout.addWidget(self.canvas0)
        self.boxLayout.addWidget(self.canvas1)
        self.boxLayout.addWidget(self.canvas2)

        self.canvas0_plot = self.canvas0.figure.subplots()
        self.canvas0_plot.axes.bar(range(0, 256),
                                   self.hist1[:, 2],
                                   color="red")
        self.canvas0.draw()

        self.canvas1_plot = self.canvas1.figure.subplots()
        self.canvas1_plot.axes.bar(range(0, 256),
                                   self.hist1[:, 1],
                                   color="green")
        self.canvas1.draw()

        self.canvas2_plot = self.canvas2.figure.subplots()
        self.canvas2_plot.axes.bar(range(0, 256),
                                   self.hist1[:, 0],
                                   color="blue")
        self.canvas2.draw()

        self.label.setAlignment(Qt.AlignCenter)

        self.inputLoaded = True

    def openTargetImage(self):
        # This function is called when the user clicks File->Target Image.

        # The QLabel where we can display an Image
        self.label2 = QLabel(self)
        self.boxLayout2 = QVBoxLayout(self.groupBox2)
        self.boxLayout2.addWidget(self.label2)

        # The image
        self.imagePath2, _ = QFileDialog.getOpenFileName(self, 'OpenFile')
        self.pixmap2 = QPixmap(self.imagePath2)
        self.label2.setPixmap(self.pixmap2)

        # Histogram of image
        self.histimage2 = cv2.imread(self.imagePath2)
        self.hist2 = histogram(self.histimage2)

        self.canvas3 = FigureCanvas(Figure(figsize=(5, 3)))
        self.canvas4 = FigureCanvas(Figure(figsize=(5, 3)))
        self.canvas5 = FigureCanvas(Figure(figsize=(5, 3)))

        self.boxLayout2.addWidget(self.canvas3)
        self.boxLayout2.addWidget(self.canvas4)
        self.boxLayout2.addWidget(self.canvas5)

        self.canvas3_plot = self.canvas3.figure.subplots()
        self.canvas3_plot.axes.bar(range(0, 256),
                                   self.hist2[:, 2],
                                   color="red")
        self.canvas3.draw()

        self.canvas4_plot = self.canvas4.figure.subplots()
        self.canvas4_plot.axes.bar(range(0, 256),
                                   self.hist2[:, 1],
                                   color="green")
        self.canvas4.draw()

        self.canvas5_plot = self.canvas5.figure.subplots()
        self.canvas5_plot.axes.bar(range(0, 256),
                                   self.hist2[:, 0],
                                   color="blue")
        self.canvas5.draw()

        self.label2.setAlignment(Qt.AlignCenter)

        self.targetLoaded = True

    def histogramButtonClicked(self):

        if not self.inputLoaded and not self.targetLoaded:
            # Error: "First load input and target images" in MessageBox
            QMessageBox.about(self, "Error",
                              "First load input and target images")

        elif not self.inputLoaded:
            # Error: "Load input image" in MessageBox
            QMessageBox.about(self, "Error", "Load input image")

        elif not self.targetLoaded:
            # Error: "Load target image" in MessageBox
            QMessageBox.about(self, "Error", "Load target image")

        else:

            self.label3 = QLabel(self)
            self.boxLayout3 = QVBoxLayout(self.groupBox3)
            self.boxLayout3.addWidget(self.label3)

            # The image
            self.image1 = cv2.imread(self.imagePath)
            self.image2 = cv2.imread(self.imagePath2)

            self.h1 = histogram(self.image1)
            self.h2 = histogram(self.image2)

            c1_0 = cdf(self.h1[:, 0])
            c2_0 = cdf(self.h2[:, 0])

            c1_1 = cdf(self.h1[:, 1])
            c2_1 = cdf(self.h2[:, 1])

            c1_2 = cdf(self.h1[:, 2])
            c2_2 = cdf(self.h2[:, 2])

            LUT0 = lookup_table(c1_0, c2_0)
            LUT1 = lookup_table(c1_1, c2_1)
            LUT2 = lookup_table(c1_2, c2_2)

            out_im0 = histogram_match(LUT0, self.image1, 0)
            out_im1 = histogram_match(LUT1, self.image1, 1)
            out_im2 = histogram_match(LUT2, self.image1, 2)

            self.out_im = np.dstack((out_im0, out_im1, out_im2))

            self.hist3 = histogram(self.out_im)

            self.out_im = np.divide(self.out_im, 255)

            self.output_image = self.out_im[..., ::-1]

            plt.imsave("outputt.png", self.output_image)

            self.pixmap3 = QPixmap("outputt.png")
            self.label3.setPixmap(self.pixmap3)

            # Histogram of image
            self.canvas6 = FigureCanvas(Figure(figsize=(5, 3)))
            self.canvas7 = FigureCanvas(Figure(figsize=(5, 3)))
            self.canvas8 = FigureCanvas(Figure(figsize=(5, 3)))

            self.boxLayout3.addWidget(self.canvas6)
            self.boxLayout3.addWidget(self.canvas7)
            self.boxLayout3.addWidget(self.canvas8)

            self.canvas6_plot = self.canvas6.figure.subplots()
            self.canvas6_plot.axes.bar(range(0, 256),
                                       self.hist3[:, 2],
                                       color="red")
            self.canvas6.draw()

            self.canvas7_plot = self.canvas7.figure.subplots()
            self.canvas7_plot.axes.bar(range(0, 256),
                                       self.hist3[:, 1],
                                       color="green")
            self.canvas7.draw()

            self.canvas8_plot = self.canvas8.figure.subplots()
            self.canvas8_plot.axes.bar(range(0, 256),
                                       self.hist3[:, 0],
                                       color="blue")
            self.canvas8.draw()

            self.label3.setAlignment(Qt.AlignCenter)

            self.label3.show()

    def quitProgram(self):

        return QApplication.exit(0)
class new_Dialog(QDialog, UI2.Ui_Data_Dialog):
    def __init__(self, parent):
        super(new_Dialog, self).__init__(parent)
        self.setupUi(self)
        self.w = parent.w
        self.h = parent.h
        self.setFixedSize(self.w, self.h)
        self.data = parent.series_1
        self.r = parent.r
        self.c = parent.c
        self.colum = self.c
        self.colum_arr = [x for x in range(self.c)]
        self.fig = plt.Figure()
        self.canvas = FigureCanvas(self.fig)
        self.graph_view.addWidget(self.canvas)
        self.graph_frame.addLayout(self.graph_view)
        self.setLayout(self.graph_frame)

        self.setupUI(self.data, self.r, self.c)

        self.show()

    def setupUI(self, data, r, c):
        self.origin_data = self.data
        self.origin_col = self.c
        self.changeheader()

        self.Save_Button.clicked.connect(self.saveFunction)
        self.Training_Button.clicked.connect(self.training_btn)

        self.formLayout_3 = QFormLayout(self.scrollAreaWidgetContents)
        self.formLayout_3.setObjectName("formLayout_3")
        for i in range(c):
            self.checkbox = QCheckBox(self.scrollAreaWidgetContents)
            self.checkbox.setMinimumSize(QSize(0, 30))
            self.checkbox.setObjectName(f"checkbox_{i}")
            self.checkbox.setText(data.columns[i])
            self.formLayout_3.setWidget(i, QFormLayout.LabelRole,
                                        self.checkbox)

        self.del_Col.clicked.connect(self.del_columns)
        self.reset_Col.clicked.connect(
            lambda state, origin_data=self.origin_data: self.all_reset(
                state, self.origin_data, self.origin_col))

        self.draw_graph()

        # 결측치 처리
        self.text = self.data.isnull().sum()
        self.formLayout_2 = QFormLayout(self.scrollAreaWidgetContents_3)
        self.formLayout_2.setObjectName("formLayout_2")
        for i in range(c):
            self.label = QLabel(self.scrollAreaWidgetContents_3)
            self.label.setMinimumSize(QSize(0, 30))
            self.label.setObjectName(f'label_{i}')
            self.formLayout_2.setWidget(i, QFormLayout.LabelRole, self.label)
            self.label.setText(data.columns[i])

            self.combo = QComboBox(self.scrollAreaWidgetContents_3)
            self.combo.setMinimumHeight(30)
            self.combo.setObjectName(f'comboBox_{i}')
            self.combo.addItem('제거')
            self.combo.addItem('0으로 대체')
            self.combo.addItem('평균값으로 대체')
            self.combo.addItem('중앙값으로 대체')
            self.formLayout_2.setWidget(i, QFormLayout.FieldRole, self.combo)
        self.radioButton.setChecked(True)
        self.process_Button.clicked.connect(
            lambda state, origin_col=self.origin_col: self.process_btn(
                state, self.origin_col))
        self.reset_Button.clicked.connect(
            lambda state, origin_data=self.origin_data: self.reset_btn(
                state, self.origin_data))

        column_headers = data.columns

        self.tableWidget.resize(500, 300)
        if r >= 200:
            r = 200
        self.tableWidget.setRowCount(r)
        self.tableWidget.setColumnCount(c)
        self.tableWidget.setHorizontalHeaderLabels(column_headers)

        for i in range(r):
            for j in range(c):
                self.tableWidget.setItem(
                    i, j, QTableWidgetItem(str(data.iloc[i, j])))
        self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)

        self.groupBox.setMinimumWidth(self.w // 3 * 0.9)
        self.groupBox_2.setMinimumWidth(self.w // 3 * 0.9)
        self.groupBox_3.setMinimumWidth(self.w // 3 * 0.9)
        self.groupBox_4.setMinimumWidth(self.w // 2 * 0.9)
        self.groupBox_5.setMinimumWidth(self.w // 2 * 0.9)

    def changeheader(self):
        # 컬럼명 변경
        self.formLayout = QFormLayout(self.scrollAreaWidgetContents_2)
        self.formLayout.setObjectName("formLayout")
        for idx in range(self.c):
            self.label = QLabel(self.scrollAreaWidgetContents_2)
            self.label.setMinimumSize(QSize(0, 30))

            self.label.setObjectName(f"label_{idx}")
            self.formLayout.setWidget(idx, QFormLayout.LabelRole, self.label)
            self.label.setText(self.data.columns[idx])

            self.lineEdit = QLineEdit(self.scrollAreaWidgetContents_2)
            self.lineEdit.setMinimumSize(QSize(0, 30))
            self.lineEdit.setObjectName(f"lineEdit_{idx}")
            self.formLayout.setWidget(idx, QFormLayout.FieldRole,
                                      self.lineEdit)
        self.pushButton = QPushButton('변경', self.groupBox_2)
        self.pushButton.setObjectName("changeButton")
        self.pushButton.clicked.connect(self.changeTextFunction)
        self.pushButton.setMaximumWidth(100)
        self.gridLayout_4.addWidget(self.pushButton, 2, 0, 1, 1, Qt.AlignRight)

    # 컬럼 header 변경
    def changeTextFunction(self):
        cnt = 0
        for i in self.colum_arr:
            try:
                text = self.findChild(QLineEdit, f"lineEdit_{i}").text()
                if text != '':
                    # self.data.columns.values[cnt] = text
                    self.data.rename(
                        columns={self.data.columns.values[cnt]: text},
                        inplace=True)
                    self.findChild(QCheckBox, f"checkbox_{i}").setText(text)
                cnt += 1
                self.findChild(QLineEdit, f"lineEdit_{i}").clear()
            except:
                pass
        self.tableWidget.setHorizontalHeaderLabels(self.data.columns)

    # Tabel cell 내용 변경
    def changeTableCells(self, r, c):
        for i in range(r):
            for j in range(c):
                self.tableWidget.setItem(
                    i, j, QTableWidgetItem(str(self.data.iloc[i, j])))
        self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)

    # 전처리
    def process_btn(self, state, origin_col):
        if self.radioButton.isChecked():
            if self.all_comboBox.currentText() == '제거':
                self.data = self.data.dropna()
                self.r = self.data.shape[0]
                self.c = self.data.shape[1]
            elif self.all_comboBox.currentText() == '0으로 대체':
                self.data = self.data.fillna(0)
            elif self.all_comboBox.currentText() == '평균값으로 대체':
                self.data = round(self.data.fillna(self.data.mean()))
            elif self.all_comboBox.currentText() == '중앙값으로 대체':
                self.data = round(self.data.fillna(self.data.median()))

        else:
            n = 0
            for i in range(origin_col):
                combo = self.findChild(QComboBox, f"comboBox_{i}")
                if combo == None:
                    n += 1
                if combo != None:
                    combo = combo.currentText()
                    if combo == '제거':
                        self.data = self.data.dropna(
                            subset=[self.data.columns[i - n]])
                        self.r = self.data.shape[0]
                    elif combo == '0으로 대체':
                        self.data[self.data.columns[i - n]] = self.data[
                            self.data.columns[i - n]].fillna(0)
                    elif combo == '평균값으로 대체':
                        self.data[self.data.columns[i - n]] = self.data[
                            self.data.columns[i - n]].fillna(
                                self.data[self.data.columns[i - n]].mean())
                    elif combo == '중앙값으로 대체':
                        self.data[self.data.columns[i - n]] = round(
                            self.data[self.data.columns[i - n]].fillna(
                                self.data[self.data.columns[i - n]].median()))
        return self.changeTableCells(self.r, self.c), self.draw_graph()

    # graph 그리기
    def draw_graph(self):
        self.fig.clear()
        ax = self.fig.add_subplot(1, 1, 1)

        missing = self.data.isnull().sum()
        x_val = []
        y_val = []
        for i in range(self.data.shape[1]):
            cnt = self.data[self.data.columns[i]].isnull().sum()
            try:
                if cnt:
                    x_val.append(self.data.columns[i])
                    y_val.append(cnt)
                else:
                    x_val.append(self.data.columns[i])
                    y_val.append(0)
            except:
                pass

        try:
            missing = missing[missing > 0]
            missing.sort_values(inplace=True)
            ax.bar(x_val, y_val)
            ax.set_ylabel('개수')
            for i, v in enumerate(x_val):
                ax.text(v, y_val[i], str(y_val[i]))
            plt.bar(x_val, y_val)
            plt.close()

        except:
            ax.bar(x_val, y_val)
            ax.set_xlabel('Column')
            ax.set_ylabel('개수')
            for i, v in enumerate(x_val):
                ax.text(y_val[i], v, str(y_val[i]))

        ax.grid()
        self.canvas.draw()

    # column 삭제
    def del_columns(self):
        cnt = 0
        for i in range(self.colum):
            try:
                if self.findChild(QCheckBox, f"checkbox_{i}").isChecked():
                    col_name = self.findChild(QCheckBox,
                                              f"checkbox_{i}").text()
                    self.data = self.data.drop(col_name, axis=1)
                    cnt += 1
                    label = self.formLayout.labelForField(
                        self.findChild(QLineEdit, f"lineEdit_{i}"))
                    label.deleteLater()
                    self.findChild(QLineEdit, f"lineEdit_{i}").deleteLater()
                    combo_label = self.formLayout_2.labelForField(
                        self.findChild(QComboBox, f"comboBox_{i}"))
                    combo_label.deleteLater()
                    self.findChild(QComboBox, f"comboBox_{i}").deleteLater()
                    self.findChild(QCheckBox, f"checkbox_{i}").deleteLater()
                    self.colum_arr.remove(i)
            except:
                pass
        self.c -= cnt
        self.tableWidget.clear()
        self.tableWidget.setHorizontalHeaderLabels(self.data.columns)
        return self.changeTableCells(self.r, self.c), self.draw_graph()

    # 데이터 초기화
    def reset_btn(self, state, origin_data):
        self.data = origin_data
        self.colum = self.c
        self.colum_arr = [x for x in range(self.c)]
        return self.changeTableCells(self.r, self.c), self.draw_graph()

    # column 초기화
    def all_reset(self, state, origin_data, origin_col):
        self.data = origin_data
        self.c = origin_col
        self.colum = self.c
        self.colum_arr = [x for x in range(self.c)]
        for i in range(self.c):
            if self.findChild(QLabel, f"label_{i}") == None:
                self.label = QLabel(self.scrollAreaWidgetContents_2)
                self.label.setMinimumSize(QSize(0, 30))
                self.label.setObjectName(f"label_{i}")
                self.formLayout.setWidget(i, QFormLayout.LabelRole, self.label)
                self.label.setText(self.data.columns[i])
                self.lineEdit = QLineEdit(self.scrollAreaWidgetContents_2)
                self.lineEdit.setMinimumSize(QSize(0, 30))
                self.lineEdit.setObjectName(f"lineEdit_{i}")
                self.formLayout.setWidget(i, QFormLayout.FieldRole,
                                          self.lineEdit)

                self.label = QLabel(self.scrollAreaWidgetContents_3)
                self.label.setMinimumSize(QSize(0, 30))
                self.label.setObjectName(f'label_{i}')
                self.formLayout_2.setWidget(i, QFormLayout.LabelRole,
                                            self.label)
                self.label.setText(self.data.columns[i])

                self.combo = QComboBox(self.scrollAreaWidgetContents_3)
                self.combo.setMinimumHeight(30)
                self.combo.setObjectName(f'comboBox_{i}')
                self.combo.addItem('제거')
                self.combo.addItem('0으로 대체')
                self.combo.addItem('평균값으로 대체')
                self.combo.addItem('중앙값으로 대체')
                self.formLayout_2.setWidget(i, QFormLayout.FieldRole,
                                            self.combo)

                self.checkbox = QCheckBox(self.scrollAreaWidgetContents)
                self.checkbox.setMinimumSize(QSize(0, 30))
                self.checkbox.setObjectName(f"checkbox_{i}")
                self.checkbox.setText(self.data.columns[i])
                self.formLayout_3.setWidget(i, QFormLayout.LabelRole,
                                            self.checkbox)
        self.tableWidget.setHorizontalHeaderLabels(self.data.columns)
        return self.changeTableCells(self.r, self.c), self.draw_graph()

    # 데이터 저장
    def saveFunction(self):
        try:
            csv = self.data
            savefile = QFileDialog.getSaveFileName(self, '파일저장', '', '(*.csv)')
            csv.to_csv(savefile[0], index=False)
        except:
            return

    # training과 연동
    def training_btn(self):
        self.series_1 = self.data
        Train_Dialog.Train_Dialog(self)
        self.close()
Beispiel #41
0
 def draw(self):
     if self.limitsSet:
         self.ax.set_xlim(self.xmin, self.xmax)
         self.ax.set_ylim(self.ymin, self.ymax)
     FigureCanvas.draw(self)
Beispiel #42
0
class Window(QDialog):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure)
        self.toolbar = NavigationToolbar(self.canvas, self)
        self.button = QPushButton('Start Scan')
        self.button.clicked.connect(self.plot)

        layout = QVBoxLayout()
        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)
        layout.addWidget(self.button)
        self.setLayout(layout)

    def plot(self):
        n = 1
        posY = 0
        posX = 0
        x1 = np.arange(0, 32, 1)
        y1 = np.arange(0, 50, 1)
        xs1, ys1 = np.meshgrid(x1, y1)
        zz1 = np.array([
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #1
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #2
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #3
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #4
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #5
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #6
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #7
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #8
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #9
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #10
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #11
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #12
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #13
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #14
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #15
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #16
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #17
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #18
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #19
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #20
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #21
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #22
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #23
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #24
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #25
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #26
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #27
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #28
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #29
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #30
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #31
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #32
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #33
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #34
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #35
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #36
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #37
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #37
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #39 
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #40 
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #41 
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #42 
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #43 
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #44 
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #45 
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #46 
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #47 
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #48 
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ],  #49        
            [
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            ]
        ])  #50

        for y in zz1:
            # Y Ganjil -> dari kiri ke kanan
            if (n == 1):
                posX = 0
                for x in y:
                    # lakukan scan ultrasonic
                    zz1[posY][posX] = get_range()
                    print(zz1[posY][posX])
                    posX += 1
                    self.figure.clear()
                    ax = Axes3D(self.figure)
                    ax.plot_surface(xs1,
                                    ys1,
                                    zz1,
                                    rstride=1,
                                    cstride=1,
                                    cmap=cm.coolwarm)
                    self.canvas.draw()
                    self.canvas.flush_events()
                    stepA(True, 1000, 100)
                n = 0
                stepB(True, 1000, 100)
            # Y Genap -> dari kanan ke kiri
            else:
                posX -= 1
                for x in reversed(y):
                    # lakukan scan ultrasonic
                    zz1[posY][posX] = get_range()
                    print(zz1[posY][posX])
                    posX -= 1
                    self.figure.clear()
                    ax = Axes3D(self.figure)
                    ax.plot_surface(xs1,
                                    ys1,
                                    zz1,
                                    rstride=1,
                                    cstride=1,
                                    cmap=cm.coolwarm)
                    self.canvas.draw()
                    self.canvas.flush_events()
                    stepA(False, 1000, 100)
                n = 1
                stepB(True, 1000, 100)
            posY += 1
        print(zz1)
        reset()
Beispiel #43
0
class DetachablePlotFrame(QtWidgets.QFrame):
    def __init__(self, parent):
        super().__init__(parent)
        self.figure = None
        self.canvas = None
        self.toolbar = None

        self.btn_detach = QtWidgets.QPushButton(self)
        self.btn_detach.setIcon(QtGui.QIcon.fromTheme('document-new-symbolic'))
        self.btn_detach.clicked.connect(self.detach_plot)

        self.btn_export = QtWidgets.QPushButton(self)
        self.btn_export.setIcon(QtGui.QIcon.fromTheme('document-save-symbolic'))
        self.btn_export.clicked.connect(self.save_plot)

        self.layout = QtWidgets.QGridLayout(self)
        self.layout.setRowStretch(0, 1)
        self.layout.addWidget(self.btn_export, 1, 1, 1, 1)
        self.btn_export.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.MinimumExpanding)
        self.layout.addWidget(self.btn_detach, 0, 1, 1, 1)
        self.btn_detach.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
        self.resize(600, 400)

    def save_plot(self):
        filepath, ok = QtWidgets.QFileDialog.getSaveFileName(self, 'Enregistrer le graphique', filter='*.png')
        if ok:
            self.figure.savefig(filepath, bbox_inches='tight')

    def detach_plot(self):
        new_window = QtWidgets.QMainWindow(self)
        new_window.setWindowTitle('Graphique détaché')

        frame = QtWidgets.QFrame(new_window)

        canvas = FigureCanvas(self.figure)
        canvas.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        canvas.updateGeometry()
        canvas.draw()

        toolbar = NavigationToolbar(canvas, frame)

        layout = QtWidgets.QVBoxLayout(frame)
        layout.addWidget(canvas, 1)
        layout.addWidget(toolbar, 0)

        new_window.setCentralWidget(frame)
        new_window.show()

        return new_window

    def update_figure(self, figure):
        self.figure = figure

        if self.canvas is not None:
            self.layout.removeWidget(self.canvas)
            self.layout.removeWidget(self.toolbar)
            self.canvas.deleteLater()

        self.canvas = FigureCanvas(self.figure)
        self.canvas.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        self.canvas.updateGeometry()
        self.canvas.draw()

        self.layout.addWidget(self.canvas, 0, 0, 2, 1)
Beispiel #44
0
class MyWindow(QWidget):
    def __init__(self):
        super().__init__()

        # plus 상태 체크
        if InitPlusCheck() == False:
            exit()

        # 기본 변수들
        self.chartData = {}
        self.code = ''
        self.isRq = False

        self.objChart = CpFutureChart()

        self.sizeControl()
        # 선물 종목 코드 추가
        for i in range(g_objFutureMgr.GetCount()):
            code = g_objFutureMgr.GetData(0, i)
            self.comboStg.addItem(code)
        self.comboStg.setCurrentIndex(0)

    def sizeControl(self):
        # 윈도우 버튼 배치
        self.setWindowTitle("PLUS API TEST")

        self.setGeometry(50, 50, 1200, 600)
        self.comboStg = QComboBox()
        # self.comboStg.move(20, nH)
        self.comboStg.currentIndexChanged.connect(self.comboChanged)
        # self.comboStg.resize(100, 30)
        self.label = QLabel('종목코드')
        # self.label.move(140, nH)

        # Figure 를 먼저 만들고 레이아웃에 들어 갈 sub axes 를 생성 한다.
        self.fig = plt.Figure()
        self.canvas = FigureCanvas(self.fig)

        # top layout
        topLayout = QHBoxLayout()
        topLayout.addWidget(self.comboStg)
        topLayout.addWidget(self.label)
        topLayout.addStretch(1)
        # topLayout.addSpacing(20)

        chartlayout = QVBoxLayout()
        chartlayout.addWidget(self.canvas)

        layout = QVBoxLayout()
        layout.addLayout(topLayout)
        layout.addLayout(chartlayout)
        layout.setStretchFactor(topLayout, 0)
        layout.setStretchFactor(chartlayout, 1)

        self.setLayout(layout)

    # 분차트 받기
    def RequestMinchart(self):
        if self.objChart.RequestMT(self.code, ord('m'), 100, self) == False:
            exit()

    def makeMovingAverage(self, maData, interval):
        # maData = []
        for i in range(0, len(self.chartData[C_DT])):
            if (i < interval):
                maData.append(float('nan'))
                continue
            sum = 0
            for j in range(0, interval):
                sum += self.chartData[C_CP][i - j]
            ma = sum / interval
            maData.append(ma)
        # print(maData)

    def drawMinchart(self):
        # 기존 거 지운다.
        self.fig.clf()

        # 211 - 2(행) * 1(열) 배치 1번째
        self.ax1 = self.fig.add_subplot(2, 1, 1)
        # 212 - 2(행) * 1(열) 배치 2번째
        self.ax2 = self.fig.add_subplot(2, 1, 2)

        ###############################################
        # 봉차트 그리기
        # self.ax1.xaxis.set_major_formatter(ticker.FixedFormatter(schartData[C_TM]))
        matfin.candlestick2_ohlc(self.ax1, self.chartData[C_OP], self.chartData[C_HP], self.chartData[C_LP],
                                 self.chartData[C_CP],
                                 width=0.8, colorup='r', colordown='b')

        ###############################################
        # x 축 인덱스 만들기 - 기본 순차 배열 추가
        x_tick_raw = [i for i in range(len(self.chartData[C_DT]))]
        # x 축 인덱스 만들기 - 실제 화면에 표시될 텍스트 만들기
        x_tick_labels = []

        startDate = 0
        dateChanged = True
        for i in range(len(self.chartData[C_DT])):
            # 날짜 변경 된 경우 날짜 정보 저장
            date = self.chartData[C_DT][i]
            if (date != startDate):
                yy, mm = divmod(date, 10000)
                mm, dd = divmod(mm, 100)
                sDate = '%2d/%d ' % (mm, dd)
                print(sDate)
                startDate = date
                dateChanged = True

            # 0 분 또는 30분 단위로 시간 표시
            hhh, mmm = divmod(self.chartData[C_TM][i], 100)
            stime = '%02d:%02d' % (hhh, mmm)
            if (mmm == 0 or mmm == 30):
                if dateChanged == True:
                    sDate += stime
                    x_tick_labels.append(sDate)
                    dateChanged = False
                else:
                    x_tick_labels.append(stime)
            else:
                x_tick_labels.append('')

        ###############################################
        # 이동 평균 그리기
        self.ax1.plot(x_tick_raw, self.chartData[C_MA5], label='ma5')
        self.ax1.plot(x_tick_raw, self.chartData[C_MA10], label='ma10')
        self.ax1.plot(x_tick_raw, self.chartData[C_MA20], label='ma20')

        ###############################################
        # 거래량 그리기
        self.ax2.bar(x_tick_raw, self.chartData[C_VL])

        ###############################################
        # x 축 가로 인덱스 지정
        self.ax1.set(xticks=x_tick_raw, xticklabels=x_tick_labels)
        self.ax2.set(xticks=x_tick_raw, xticklabels=x_tick_labels)

        self.ax1.grid()
        self.ax2.grid()
        plt.tight_layout()
        self.ax1.legend(loc='upper left')

        self.canvas.draw()

    def comboChanged(self):
        if self.isRq == True:
            return
        self.isRq = True
        self.code = self.comboStg.currentText()
        self.name = g_objFutureMgr.CodetoName(self.code)
        self.label.setText(self.name)
        self.RequestMinchart()
        self.makeMovingAverage(self.chartData[C_MA5], 5)
        self.makeMovingAverage(self.chartData[C_MA10], 10)
        self.makeMovingAverage(self.chartData[C_MA20], 20)
        self.drawMinchart()
        self.isRq = False
Beispiel #45
0
class FigureTab:
  cursors = [15000, 45000]
  colors = ['orange', 'violet']

  def __init__(self, layout, vna):
    # create figure
    self.figure = Figure()
    if sys.platform != 'win32':
      self.figure.set_facecolor('none')
    self.canvas = FigureCanvas(self.figure)
    layout.addWidget(self.canvas)
    # create navigation toolbar
    self.toolbar = NavigationToolbar(self.canvas, None, False)
    self.toolbar.layout().setSpacing(6)
    # remove subplots action
    actions = self.toolbar.actions()
    if int(matplotlib.__version__[0]) < 2:
      self.toolbar.removeAction(actions[7])
    else:
      self.toolbar.removeAction(actions[6])
    self.toolbar.addSeparator()
    self.cursorLabels = {}
    self.cursorValues = {}
    self.cursorMarkers = {}
    self.cursorPressed = {}
    for i in range(len(self.cursors)):
      self.cursorMarkers[i] = None
      self.cursorPressed[i] = False
      self.cursorLabels[i] = QLabel('Cursor %d, kHz' % (i + 1))
      self.cursorLabels[i].setStyleSheet('color: %s' % self.colors[i])
      self.cursorValues[i] = QSpinBox()
      self.cursorValues[i].setMinimumSize(90, 0)
      self.cursorValues[i].setSingleStep(10)
      self.cursorValues[i].setAlignment(Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter)
      self.toolbar.addWidget(self.cursorLabels[i])
      self.toolbar.addWidget(self.cursorValues[i])
      self.cursorValues[i].valueChanged.connect(partial(self.set_cursor, i))
      self.canvas.mpl_connect('button_press_event', partial(self.press_marker, i))
      self.canvas.mpl_connect('motion_notify_event', partial(self.move_marker, i))
      self.canvas.mpl_connect('button_release_event', partial(self.release_marker, i))
    self.toolbar.addSeparator()
    self.plotButton = QPushButton('Rescale')
    self.toolbar.addWidget(self.plotButton)
    layout.addWidget(self.toolbar)
    self.plotButton.clicked.connect(self.plot)
    self.mode = None
    self.vna = vna

  def add_cursors(self, axes):
    if self.mode == 'gain_short' or self.mode == 'gain_open':
      columns = ['Freq., kHz', 'G, dB', r'$\angle$ G, deg']
    else:
      columns = ['Freq., kHz', 'Re(Z), \u03A9', 'Im(Z), \u03A9', '|Z|, \u03A9', r'$\angle$ Z, deg', 'SWR', r'|$\Gamma$|', r'$\angle$ $\Gamma$, deg', 'RL, dB']
    y = len(self.cursors) * 0.04 + 0.01
    for i in range(len(columns)):
      self.figure.text(0.19 + 0.1 * i, y, columns[i], horizontalalignment = 'right')
    self.cursorRows = {}
    for i in range(len(self.cursors)):
      y = len(self.cursors) * 0.04 - 0.03 - 0.04 * i
      self.figure.text(0.01, y, 'Cursor %d' % (i + 1), color = self.colors[i])
      self.cursorRows[i] = {}
      for j in range(len(columns)):
        self.cursorRows[i][j] = self.figure.text(0.19 + 0.1 * j, y, '', horizontalalignment = 'right')
      if self.mode == 'smith':
        self.cursorMarkers[i], = axes.plot(0.0, 0.0, marker = 'o', color = self.colors[i])
      else:
        self.cursorMarkers[i] = axes.axvline(0.0, color = self.colors[i], linewidth = 2)
      self.set_cursor(i, self.cursorValues[i].value())

  def set_cursor(self, index, value):
    FigureTab.cursors[index] = value
    marker = self.cursorMarkers[index]
    if marker is None: return
    row = self.cursorRows[index]
    freq = value
    gamma = self.vna.gamma(freq)
    if self.mode == 'smith':
      marker.set_xdata(gamma.real)
      marker.set_ydata(gamma.imag)
    else:
      marker.set_xdata(freq)
    row[0].set_text('%d' % freq)
    if self.mode == 'gain_short':
      gain = self.vna.gain_short(freq)
      magnitude = 20.0 * np.log10(np.absolute(gain))
      angle = np.angle(gain, deg = True)
      row[1].set_text(unicode_minus('%.1f' % magnitude))
      row[2].set_text(unicode_minus('%.1f' % angle))
    elif self.mode == 'gain_open':
      gain = self.vna.gain_open(freq)
      magnitude = 20.0 * np.log10(np.absolute(gain))
      angle = np.angle(gain, deg = True)
      row[1].set_text(unicode_minus('%.1f' % magnitude))
      row[2].set_text(unicode_minus('%.1f' % angle))
    else:
      swr = self.vna.swr(freq)
      z = self.vna.impedance(freq)
      rl = 20.0 * np.log10(np.absolute(gamma))
      if rl > -0.01: rl = 0.0
      row[1].set_text(metric_prefix(z.real))
      row[2].set_text(metric_prefix(z.imag))
      row[3].set_text(metric_prefix(np.absolute(z)))
      angle = np.angle(z, deg = True)
      if np.abs(angle) < 0.1: angle = 0.0
      row[4].set_text(unicode_minus('%.1f' % angle))
      row[5].set_text(unicode_minus('%.2f' % swr))
      row[6].set_text(unicode_minus('%.2f' % np.absolute(gamma)))
      angle = np.angle(gamma, deg = True)
      if np.abs(angle) < 0.1: angle = 0.0
      row[7].set_text(unicode_minus('%.1f' % angle))
      row[8].set_text(unicode_minus('%.2f' % rl))
    self.canvas.draw()

  def press_marker(self, index, event):
    if not event.inaxes: return
    if self.mode == 'smith': return
    marker = self.cursorMarkers[index]
    if marker is None: return
    contains, misc = marker.contains(event)
    if not contains: return
    self.cursorPressed[index] = True

  def move_marker(self, index, event):
    if not event.inaxes: return
    if self.mode == 'smith': return
    if not self.cursorPressed[index]: return
    self.cursorValues[index].setValue(event.xdata)

  def release_marker(self, index, event):
    self.cursorPressed[index] = False

  def xlim(self, freq):
    start = freq[0]
    stop = freq[-1]
    min = np.minimum(start, stop)
    max = np.maximum(start, stop)
    margin = (max - min) / 50
    return (min - margin, max + margin)

  def plot(self):
    getattr(self, 'plot_%s' % self.mode)()

  def update(self, mode):
    start = self.vna.dut.freq[0]
    stop = self.vna.dut.freq[-1]
    min = np.minimum(start, stop)
    max = np.maximum(start, stop)
    for i in range(len(self.cursors)):
      value = self.cursors[i]
      self.cursorValues[i].setRange(min, max)
      self.cursorValues[i].setValue(value)
      self.set_cursor(i, value)
    getattr(self, 'update_%s' % mode)()

  def plot_curves(self, freq, data1, label1, limit1, data2, label2, limit2):
    matplotlib.rcdefaults()
    matplotlib.rcParams['axes.formatter.use_mathtext'] = True
    self.figure.clf()
    bottom = len(self.cursors) * 0.04 + 0.13
    self.figure.subplots_adjust(left = 0.16, bottom = bottom, right = 0.84, top = 0.96)
    axes1 = self.figure.add_subplot(111)
    axes1.cla()
    axes1.xaxis.grid()
    axes1.set_xlabel('kHz')
    axes1.set_ylabel(label1)
    xlim = self.xlim(freq)
    axes1.set_xlim(xlim)
    if limit1 is not None: axes1.set_ylim(limit1)
    self.curve1, = axes1.plot(freq, data1, color = 'blue', label = label1)
    self.add_cursors(axes1)
    if data2 is None:
      self.canvas.draw()
      return
    axes1.tick_params('y', color = 'blue', labelcolor = 'blue')
    axes1.yaxis.label.set_color('blue')
    axes2 = axes1.twinx()
    axes2.spines['left'].set_color('blue')
    axes2.spines['right'].set_color('red')
    axes2.set_ylabel(label2)
    axes2.set_xlim(xlim)
    if limit2 is not None: axes2.set_ylim(limit2)
    axes2.tick_params('y', color = 'red', labelcolor = 'red')
    axes2.yaxis.label.set_color('red')
    self.curve2, = axes2.plot(freq, data2, color = 'red', label = label2)
    self.canvas.draw()

  def plot_gain(self, gain):
    freq = self.vna.dut.freq
    data1 = 20.0 * np.log10(np.absolute(gain))
    data2 = np.angle(gain, deg = True)
    self.plot_curves(freq, data1, 'G, dB', (-110, 110.0), data2, r'$\angle$ G, deg', (-198, 198))

  def plot_gain_short(self):
    self.mode = 'gain_short'
    self.plot_gain(self.vna.gain_short(self.vna.dut.freq))

  def plot_gain_open(self):
    self.mode = 'gain_open'
    self.plot_gain(self.vna.gain_open(self.vna.dut.freq))

  def update_gain(self, gain, mode):
    if self.mode == mode:
      self.curve1.set_xdata(self.vna.dut.freq)
      self.curve1.set_ydata(20.0 * np.log10(np.absolute(gain)))
      self.curve2.set_xdata(self.vna.dut.freq)
      self.curve2.set_ydata(np.angle(gain, deg = True))
      self.canvas.draw()
    else:
      self.mode = mode
      self.plot_gain(gain)

  def update_gain_short(self):
    self.update_gain(self.vna.gain_short(self.vna.dut.freq), 'gain_short')

  def update_gain_open(self):
    self.update_gain(self.vna.gain_open(self.vna.dut.freq), 'gain_open')

  def plot_magphase(self, freq, data, label, mode):
    self.mode = mode
    data1 = np.absolute(data)
    data2 = np.angle(data, deg = True)
    max = np.fmax(0.01, data1.max())
    label1 = r'|%s|' % label
    label2 = r'$\angle$ %s, deg' % label
    self.plot_curves(freq, data1, label1, (-0.05 * max, 1.05 * max), data2, label2, (-198, 198))

  def update_magphase(self, freq, data, label, mode):
    if self.mode == mode:
      self.curve1.set_xdata(freq)
      self.curve1.set_ydata(np.absolute(data))
      self.curve2.set_xdata(freq)
      self.curve2.set_ydata(np.angle(data, deg = True))
      self.canvas.draw()
    else:
      self.plot_magphase(freq, data, label, mode)

  def plot_open(self):
    self.plot_magphase(self.vna.open.freq, self.vna.open.data, 'open', 'open')

  def update_open(self):
    self.update_magphase(self.vna.open.freq, self.vna.open.data, 'open', 'open')

  def plot_short(self):
    self.plot_magphase(self.vna.short.freq, self.vna.short.data, 'short', 'short')

  def update_short(self):
    self.update_magphase(self.vna.short.freq, self.vna.short.data, 'short', 'short')

  def plot_load(self):
    self.plot_magphase(self.vna.load.freq, self.vna.load.data, 'load', 'load')

  def update_load(self):
    self.update_magphase(self.vna.load.freq, self.vna.load.data, 'load', 'load')

  def plot_dut(self):
    self.plot_magphase(self.vna.dut.freq, self.vna.dut.data, 'dut', 'dut')

  def update_dut(self):
    self.update_magphase(self.vna.dut.freq, self.vna.dut.data, 'dut', 'dut')

  def plot_smith_grid(self, axes, color):
    load = 50.0
    ticks = np.array([0.0, 0.2, 0.5, 1.0, 2.0, 5.0])
    for tick in ticks * load:
      axis = np.logspace(-4, np.log10(1.0e3), 200) * load
      z = tick + 1.0j * axis
      gamma = (z - load)/(z + load)
      axes.plot(gamma.real, gamma.imag, color = color, linewidth = 0.4, alpha = 0.3)
      axes.plot(gamma.real, -gamma.imag, color = color, linewidth = 0.4, alpha = 0.3)
      z = axis + 1.0j * tick
      gamma = (z - load)/(z + load)
      axes.plot(gamma.real, gamma.imag, color = color, linewidth = 0.4, alpha = 0.3)
      axes.plot(gamma.real, -gamma.imag, color = color, linewidth = 0.4, alpha = 0.3)
      if tick == 0.0:
        axes.text(1.0, 0.0, u'\u221E', color = color, ha = 'left', va = 'center', clip_on = True, fontsize = 'x-large')
        axes.text(-1.0, 0.0, u'0\u03A9', color = color, ha = 'left', va = 'bottom', clip_on = True)
        continue
      lab = u'%d\u03A9' % tick
      x = (tick - load) / (tick + load)
      axes.text(x, 0.0, lab, color = color, ha = 'left', va = 'bottom', clip_on = True)
      lab = u'j%d\u03A9' % tick
      z =  1.0j * tick
      gamma = (z - load)/(z + load) * 1.05
      x = gamma.real
      y = gamma.imag
      angle = np.angle(gamma) * 180.0 / np.pi - 90.0
      axes.text(x, y, lab, color = color, ha = 'center', va = 'center', clip_on = True, rotation = angle)
      lab = u'\u2212j%d\u03A9' % tick
      axes.text(x, -y, lab, color = color, ha = 'center', va = 'center', clip_on = True, rotation = -angle)

  def plot_smith(self):
    self.mode = 'smith'
    matplotlib.rcdefaults()
    self.figure.clf()
    bottom = len(self.cursors) * 0.04 + 0.05
    self.figure.subplots_adjust(left = 0.0, bottom = bottom, right = 1.0, top = 1.0)
    axes1 = self.figure.add_subplot(111)
    self.plot_smith_grid(axes1, 'blue')
    gamma = self.vna.gamma(self.vna.dut.freq)
    self.curve1, = axes1.plot(gamma.real, gamma.imag, color = 'red')
    axes1.axis('equal')
    axes1.set_xlim(-1.12, 1.12)
    axes1.set_ylim(-1.12, 1.12)
    axes1.xaxis.set_visible(False)
    axes1.yaxis.set_visible(False)
    for loc, spine in axes1.spines.items():
      spine.set_visible(False)
    self.add_cursors(axes1)
    self.canvas.draw()

  def update_smith(self):
    if self.mode == 'smith':
      gamma = self.vna.gamma(self.vna.dut.freq)
      self.curve1.set_xdata(gamma.real)
      self.curve1.set_ydata(gamma.imag)
      self.canvas.draw()
    else:
      self.plot_smith()

  def plot_imp(self):
    self.mode = 'imp'
    freq = self.vna.dut.freq
    z = self.vna.impedance(freq)
    data1 = np.fmin(9.99e4, np.absolute(z))
    data2 = np.angle(z, deg = True)
    max = np.fmax(0.01, data1.max())
    self.plot_curves(freq, data1, '|Z|, \u03A9', (-0.05 * max, 1.05 * max), data2, r'$\angle$ Z, deg', (-198, 198))

  def update_imp(self):
    if self.mode == 'imp':
      freq = self.vna.dut.freq
      z = self.vna.impedance(freq)
      data1 = np.fmin(9.99e4, np.absolute(z))
      data2 = np.angle(z, deg = True)
      self.curve1.set_xdata(freq)
      self.curve1.set_ydata(data1)
      self.curve2.set_xdata(freq)
      self.curve2.set_ydata(data2)
      self.canvas.draw()
    else:
      self.plot_imp()

  def plot_swr(self):
    self.mode = 'swr'
    freq = self.vna.dut.freq
    data1 = self.vna.swr(freq)
    self.plot_curves(freq, data1, 'SWR', (0.9, 3.1), None, None, None)

  def update_swr(self):
    if self.mode == 'swr':
      self.curve1.set_xdata(self.vna.dut.freq)
      self.curve1.set_ydata(self.vna.swr(self.vna.dut.freq))
      self.canvas.draw()
    else:
      self.plot_swr()

  def plot_gamma(self):
    self.plot_magphase(self.vna.dut.freq, self.vna.gamma(self.vna.dut.freq), r'$\Gamma$', 'gamma')

  def update_gamma(self):
    self.update_magphase(self.vna.dut.freq, self.vna.gamma(self.vna.dut.freq), r'$\Gamma$', 'gamma')

  def plot_rl(self):
    self.mode = 'rl'
    freq = self.vna.dut.freq
    gamma = self.vna.gamma(freq)
    data1 = 20.0 * np.log10(np.absolute(gamma))
    self.plot_curves(freq, data1, 'RL, dB', (-105, 5.0), None, None, None)

  def update_rl(self):
    if self.mode == 'rl':
      freq = self.vna.dut.freq
      gamma = self.vna.gamma(freq)
      data1 = 20.0 * np.log10(np.absolute(gamma))
      self.curve1.set_xdata(freq)
      self.curve1.set_ydata(data1)
      self.canvas.draw()
    else:
      self.plot_rl()
Beispiel #46
0
class Window(QtWidgets.QMainWindow, Data_to_plot):
    def __init__(self, parent=None):
        super().__init__(parent)
        wid = QWidget(self)
        self.setCentralWidget(wid)
        self.figure = plt.figure()
        self.axes = self.figure.add_subplot(111)
        # We want the axes cleared every time plot() is called
        self.axes.hold(False)
        self.canvas = FigureCanvas(self.figure)

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

        self.button_to_plot = QtWidgets.QPushButton('Plot')
        self.button_to_plot.clicked.connect(self.plot)

        self.button_to_plot_twinx = QtWidgets.QPushButton('Plot twinx')
        self.button_to_plot_twinx.clicked.connect(self.plot_twinx)

        self.button_to_zoom = QtWidgets.QPushButton('Zoom')
        self.button_to_zoom.clicked.connect(self.zoom)

        self.button_to_home = QtWidgets.QPushButton('Home')
        self.button_to_home.clicked.connect(self.home)

        self.button_to_save_fig = QtWidgets.QPushButton('Save')
        self.button_to_save_fig.clicked.connect(self.save_fig)

        self.button_to_set_xlabel = QtWidgets.QPushButton('Set xlabel')
        self.button_to_set_xlabel.clicked.connect(self.set_xlabel)
        self.text_xlable = QtWidgets.QLineEdit()

        self.button_to_set_ylabel = QtWidgets.QPushButton('Set ylabel')
        self.button_to_set_ylabel.clicked.connect(self.set_ylabel)
        self.text_ylable = QtWidgets.QLineEdit()

        self.button_to_set_title = QtWidgets.QPushButton('Set title')
        self.button_to_set_title.clicked.connect(self.set_title)
        self.text_title = QtWidgets.QLineEdit()

        self.button_to_import_data = QtWidgets.QPushButton('import data x,y')
        self.button_to_import_data.clicked.connect(self.import_data)
        self.textEdit = QtWidgets.QTextEdit()

        self.button_to_import_data_xyz = QtWidgets.QPushButton(
            'import data x,y,z')

        # set the layout
        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)

        btnlayout1 = QtWidgets.QHBoxLayout()
        btnlayout1.addWidget(self.button_to_plot)
        btnlayout1.addWidget(self.button_to_plot_twinx)
        btnlayout1.addWidget(self.button_to_zoom)
        btnlayout1.addWidget(self.button_to_home)
        btnlayout1.addWidget(self.button_to_save_fig)

        btnlayout2 = QtWidgets.QHBoxLayout()
        btnlayout2.addWidget(self.button_to_set_xlabel)
        btnlayout2.addWidget(self.button_to_set_ylabel)
        btnlayout2.addWidget(self.button_to_set_title)

        btnlayout3 = QtWidgets.QHBoxLayout()
        btnlayout3.addWidget(self.text_xlable)
        btnlayout3.addWidget(self.text_ylable)
        btnlayout3.addWidget(self.text_title)

        btnlayout4 = QtWidgets.QHBoxLayout()
        btnlayout4.addWidget(self.button_to_import_data)
        btnlayout4.addWidget(self.textEdit)
        btnlayout4.addWidget(self.button_to_import_data_xyz)

        qw = QtWidgets.QWidget(self)
        qw.setLayout(btnlayout1)

        qw2 = QtWidgets.QWidget(self)
        qw2.setLayout(btnlayout2)

        qw3 = QtWidgets.QWidget(self)
        qw3.setLayout(btnlayout3)

        qw4 = QtWidgets.QWidget(self)
        qw4.setLayout(btnlayout4)

        layout.addWidget(qw)
        layout.addWidget(qw2)
        layout.addWidget(qw3)
        layout.addWidget(qw4)

        wid.setLayout(layout)

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

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

    def import_data(self):
        fname = QtWidgets.QFileDialog.getOpenFileName(self, 'Open file',
                                                      os.getcwd())
        if fname[0]:
            try:
                self.x, self.y = np.loadtxt(fname[0], unpack=True, skiprows=1)
                with open(fname[0], 'r') as f:
                    data = f.read()
                self.textEdit.setText(data)
            except Exception as err:
                print(err)

    def import_data_xyz(self):
        fname = QtWidgets.QFileDialog.getOpenFileName(self, 'Open file',
                                                      os.getcwd())
        if fname[0]:
            try:
                self.x, self.y, self.z = np.loadtxt(fname[0],
                                                    unpack=True,
                                                    skiprows=1)
                with open(fname[0], 'r') as f:
                    data = f.read()
                self.textEdit.setText(data)
            except Exception as err:
                print(err)

    def plot(self):
        self.axes.plot(self.x, self.y, 'bo')
        self.canvas.draw()

    def plot_twinx(self):
        self.axes.plot(self.x, self.y, 'bo')
        self.axes2 = self.axes.twinx()
        self.axes2.plot(self.x, self.z, 'r<')
        self.canvas.draw()

    def set_title(self):
        self.title = self.text_title.text()
        self.axes.set_title(self.title)
        self.canvas.draw()

    def set_xlabel(self):
        self.xlabel = self.text_xlable.text()
        self.axes.set_xlabel(self.xlabel)
        self.canvas.draw()

    def set_ylabel(self):
        self.ylabel = self.text_ylable.text()
        self.axes.set_ylabel(self.ylabel)
        self.canvas.draw()

    def save_fig(self):
        path_to_save_fig = os.path.join(os.getcwd(), "wykres.jpg")
        plt.savefig(path_to_save_fig)
class PlotWindow(QtWidgets.QDialog):
    def __init__(self, parent=None, figure=None):
        super().__init__(parent)
        # a figure instance to plot on
        self.setWindowTitle('Plot Window')
        if not figure:
            self.figure = plt.figure()
        else:
            self.figure = figure
        self.time_subplot = self.figure.add_subplot(221)
        self.freq_subplot = self.figure.add_subplot(222)
        self.glue_subplot = self.figure.add_subplot(223)
        self.int_subplot = self.figure.add_subplot(224)

        # this is the Canvas Widget that displays the `figure`
        # it takes the `figure` instance as a parameter to __init__
        self.canvas = FigureCanvas(self.figure)

        # this is the Navigation widget
        # it takes the Canvas widget and a parent
        self.toolbar = NavigationToolbar(self.canvas, self)

        # Get data button
        self.get_time_button = QtWidgets.QPushButton('Get Time Data', self)
        self.get_freq_button = QtWidgets.QPushButton('Get Freq Data', self)
        self.get_glue_button = QtWidgets.QPushButton('Get Glue Data', self)
        self.get_int_button = QtWidgets.QPushButton('Get Int Data', self)

        self.get_time_button.clicked.connect(self.show_time_data)
        self.get_freq_button.clicked.connect(self.show_freq_data)
        self.get_glue_button.clicked.connect(self.show_glue_data)
        self.get_int_button.clicked.connect(self.show_int_data)

        # set the layout
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)
        hlayout = QtWidgets.QHBoxLayout(self)
        hlayout.addWidget(self.get_time_button)
        hlayout.addWidget(self.get_freq_button)
        hlayout.addWidget(self.get_glue_button)
        hlayout.addWidget(self.get_int_button)
        layout.addLayout(hlayout)
        self.setLayout(layout)

        # data
        self.time_data = None
        self.freq_data = None
        self.glue_data = None
        self.int_data = None



    def plot_time(self, dic, data, title='Time', x_label='Time'):
        # discards the old graph
        self.time_subplot.hold(False)

        uc = ng.pipe.make_uc(dic, data)
        [re, im, ab] = self.time_subplot.plot(uc.us_scale(), data.real, 'r-', uc.us_scale(), data.imag, 'g-',
                                              uc.us_scale(), np.absolute(data), 'm--')
        re.set_label('Real Part')
        im.set_label('Imag Part')
        ab.set_label('Absolute')
        self.time_subplot.legend()

        self.time_subplot.set_title(title)
        self.time_subplot.set_xlabel(x_label + ' / ' + 'us')

        # refresh canvas
        self.canvas.draw()

        # refresh data
        self.time_data = [uc.us_scale(), data.real, data.imag, np.absolute(data)]

    def show_time_data(self):
        self.show_data_dialog('time')
    def show_freq_data(self):
        self.show_data_dialog('freq')
    def show_glue_data(self):
        self.show_data_dialog('glue')
    def show_int_data(self):
        self.show_data_dialog('int')


    def show_data_dialog(self, data_type):
        message_widget = QtWidgets.QDialog(self)
        if data_type == 'time':
            message = self.format_data(header = 'Time/us\tRealPart\tImagPart\tAbs', data_list=self.time_data)
        if data_type == 'freq':
            message = self.format_data(header = 'Freq/hz\tRealPart\tImagPart\tAbs', data_list=self.freq_data)
        if data_type == 'glue':
            message = self.format_data(header = 'Freq/hz\tRealPart\tImagPart\tAbs', data_list=self.glue_data)
        if data_type == 'int':
            message = self.format_data(header = 'X0\tRealPart\tImagPart\tAbs\tX1\tRealPart\tImagPart\tAbs\tX2\tRealPart\tImagPart\tAbs\tX3\tRealPart\tImagPart\tAbs\t', data_list=self.int_data)

        message_box = QtWidgets.QTextEdit(message_widget)
        message_box.setText(message)
        layout = QtWidgets.QVBoxLayout(message_widget)
        layout.addWidget(message_box)
        message_widget.setLayout(layout)
        message_widget.setWindowTitle('Data')
        message_widget.show()

    def format_data(self, header, data_list):
        zipped_list = list(zip(*[data for data in data_list if any(data)]))
        out_text = StringIO()
        out_text.write(header+'\n')
        for item in zipped_list:
            out_text.write('\t'.join((str(item_item) for item_item in item))+'\n')
        return out_text.getvalue()

    def plot_freq(self, dic, data, title='Spectrum', x_label='Frequency Deviation'):
        # discards the old graph
        self.freq_subplot.hold(False)

        uc = ng.pipe.make_uc(dic, data)
        (re, im, ab) = self.freq_subplot.plot(uc.hz_scale(), data.real, 'r-', uc.hz_scale(), data.imag, 'g-',
                                              uc.hz_scale(), np.core.umath.absolute(data), 'm--')
        re.set_label('Real Part')
        im.set_label('Imag Part')
        ab.set_label('Absolute')
        self.freq_subplot.legend()

        self.freq_subplot.set_title(title)
        self.freq_subplot.set_xlabel(x_label + ' / ' + 'hz')

        # refresh canvas
        self.canvas.draw()

        # refresh data
        self.freq_data = [uc.hz_scale(), data.real, data.imag, np.absolute(data)]



    def plot_glue(self, x, y, y_list, title='Glue', x_label='Frequency', show = 'sum'):
        # discards the old graph
        self.glue_subplot.hold(False)

        if show == 'sum':
            (re, im, ab) = self.glue_subplot.plot(x, y.real, 'r-', x, y.imag, 'g-', x, np.core.umath.absolute(y), 'm--')
            re.set_label('Real Part')
            im.set_label('Imag Part')
            ab.set_label('Absolute')
            # refresh data
            self.glue_data = [x, y.real, y.imag, np.absolute(y)]
        else:
            self.glue_subplot.plot(x, y_list)

        self.glue_subplot.legend()
        self.glue_subplot.set_xlabel(x_label + ' / ' + 'hz')
        self.glue_subplot.set_title(title)
        # refresh canvas
        self.canvas.draw()



    def plot_int(self, int_plot_dic, title='Integral', x_label='No X Label'):
        # discards the old graph
        self.int_subplot.hold(False)

        (int_0_re, int_0_im, int_0_ab,
        int_1_re, int_1_im, int_1_ab,
        int_2_re, int_2_im, int_2_ab,
        int_3_re, int_3_im, int_3_ab,) = self.int_subplot.plot(int_plot_dic[0][0], np.asarray(int_plot_dic[0][1]).real, 'r--',
                                                               int_plot_dic[0][0], np.asarray(int_plot_dic[0][1]).imag, 'r-.',
                                                               int_plot_dic[0][0], np.core.umath.absolute(int_plot_dic[0][1]), 'r-',

                                                               int_plot_dic[1][0], np.asarray(int_plot_dic[1][1]).real, 'k--',
                                                               int_plot_dic[1][0], np.asarray(int_plot_dic[1][1]).imag, 'k-.',
                                                               int_plot_dic[1][0], np.core.umath.absolute(int_plot_dic[1][1]), 'k-',

                                                               int_plot_dic[2][0], np.asarray(int_plot_dic[2][1]).real, 'g--',
                                                               int_plot_dic[2][0], np.asarray(int_plot_dic[2][1]).imag, 'g-.',
                                                               int_plot_dic[2][0], np.core.umath.absolute(int_plot_dic[2][1]), 'g-',

                                                               int_plot_dic[3][0], np.asarray(int_plot_dic[3][1]).real, 'm--',
                                                               int_plot_dic[3][0], np.asarray(int_plot_dic[3][1]).imag, 'm-.',
                                                               int_plot_dic[3][0], np.core.umath.absolute(int_plot_dic[3][1]), 'm-')
        int_0_re.set_label('Integral 0 Re')
        int_0_im.set_label('Integral 0 Im')
        int_0_ab.set_label('Integral 0 ABS')

        int_1_re.set_label('Integral 1 Re')
        int_1_im.set_label('Integral 1 Im')
        int_1_ab.set_label('Integral 1 ABS')

        int_2_re.set_label('Integral 2 Re')
        int_2_im.set_label('Integral 2 Im')
        int_2_ab.set_label('Integral 2 ABS')

        int_3_re.set_label('Integral 3 Re')
        int_3_im.set_label('Integral 3 Im')
        int_3_ab.set_label('Integral 3 ABS')

        self.int_subplot.legend()

        self.int_subplot.set_title(title)
        self.int_subplot.set_xlabel(x_label)

        # refresh canvas
        self.canvas.draw()

        # refresh data
        self.int_data = [int_plot_dic[0][0], np.asarray(int_plot_dic[0][1]).real, np.asarray(int_plot_dic[0][1]).imag, np.core.umath.absolute(int_plot_dic[0][1]),

                                                               int_plot_dic[1][0], np.asarray(int_plot_dic[1][1]).real,  np.asarray(int_plot_dic[1][1]).imag, np.core.umath.absolute(int_plot_dic[1][1]),

                                                               int_plot_dic[2][0], np.asarray(int_plot_dic[2][1]).real,  np.asarray(int_plot_dic[2][1]).imag, np.core.umath.absolute(int_plot_dic[2][1]),

                                                               int_plot_dic[3][0], np.asarray(int_plot_dic[3][1]).real,  np.asarray(int_plot_dic[3][1]).imag, np.core.umath.absolute(int_plot_dic[3][1])]
 def draw(self):
     if self.limitsSet:
         self.ax.set_xlim(self.xmin, self.xmax)
         self.ax.set_ylim(self.ymin, self.ymax)
     FigureCanvas.draw(self)
Beispiel #49
0
class RoastGraphWidget():
    def __init__(self, graphXValueList = None, graphYValueList = None, animated = False, updateMethod = None, animatingMethod = None):
        self.graphXValueList = graphXValueList or []
        self.graphYValueList = graphYValueList or []
        self.counter = 0
        self.updateMethod = updateMethod
        self.animated = animated
        self.animatingMethod = animatingMethod # Check if graph should continue to graph

    def create_graph(self):
        # Create the graph widget.
        graphWidget = QWidget()
        graphWidget.setObjectName("graph")

        # Style attributes of matplotlib.
        plt.rcParams['lines.linewidth'] = 3
        plt.rcParams['lines.color'] = '#2a2a2a'
        plt.rcParams['font.size'] = 10.

        self.graphFigure = plt.figure(facecolor='#444952')
        self.graphCanvas = FigureCanvas(self.graphFigure)

        # Add graph widgets to layout for graph.
        graphVerticalBox = QVBoxLayout()
        graphVerticalBox.addWidget(self.graphCanvas)
        graphWidget.setLayout(graphVerticalBox)

        # Animate the the graph with new data
        if self.animated:
            animateGraph = animation.FuncAnimation(self.graphFigure,
                self.graph_draw, interval=1000)
        else:
            self.graph_draw()

        return graphWidget

    def graph_draw(self, *args, **kwargs):
        # Start graphing the roast if the roast has started.
        if self.animatingMethod():
            self.updateMethod()

        self.graphFigure.clear()

        self.graphAxes = self.graphFigure.add_subplot(111)
        self.graphAxes.plot_date(self.graphXValueList, self.graphYValueList,
            '#8ab71b')

        # Add formatting to the graphs.
        self.graphAxes.set_ylabel('TEMPERATURE (°F)')
        self.graphAxes.set_xlabel('TIME')
        self.graphFigure.subplots_adjust(bottom=0.2)

        ax = self.graphAxes.get_axes()
        ax.xaxis.set_major_formatter(DateFormatter('%M:%S'))
        ax.set_axis_bgcolor('#23252a')

        self.graphCanvas.draw()

    def append_x(self, xCoord):
        self.counter += 1
        currentTime = datetime.datetime.fromtimestamp(self.counter)
        self.graphXValueList.append(matplotlib.dates.date2num(currentTime))
        self.graphYValueList.append(xCoord)

    def clear_graph(self):
        self.graphXValueList = []
        self.graphYValueList = []
        self.counter = 0
        self.graphFigure.clear()

    def save_roast_graph(self):
        userDesktop =  os.path.expanduser('~/Desktop')
        fileName = os.path.join(userDesktop + "/Roast_Graph")

        i = 0
        while os.path.exists('{}{:d}.png'.format(fileName, i)):
            i += 1
        self.graphFigure.savefig('{}{:d}.png'.format(fileName, i))
Beispiel #50
0
class Compressor(QtWidgets.QMainWindow):
    def __init__(self):
        super(Compressor, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.input_file_name = ''
        self.output_file_name = ''

        self.ui.pushButton.clicked.connect(self.file_btn_click)
        self.ui.compButton.clicked.connect(self.compress_btn_click)
        self.ui.dirButton.clicked.connect(self.saveFileDialog)
        self.ui.decompButton.clicked.connect(self.decompress_btn_click)
        self.ui.comp_decomp_btn.clicked.connect(self.analise_click)

        self.clear_table()

    def autolabel(self, rects, ax, rotation):
        for rect in rects:
            height = rect.get_height()
            ax.annotate('{}'.format(height),
                        xy=(rect.get_x() + rect.get_width() / 2, height / 2),
                        xytext=(0, 3),
                        textcoords="offset points",
                        ha='center',
                        va='bottom',
                        rotation=rotation)

    def show_one_graph(self, uncomp, comp):

        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure)
        self.ui.verticalLayout.addWidget(self.canvas)

        color = "#" + ''.join(
            [random.choice('0123456789ABCDEF') for j in range(6)])
        axs = self.figure.subplots(gridspec_kw={'right': 0.9, 'left': 0.2})
        axs.set_title('Default/Compressed')
        axs.set_ylabel('Size, Kb')
        rects = axs.bar(['Default', 'Compressed'], [uncomp, comp], color=color)
        self.autolabel(rects, axs, 0)

    def show_graphs(self, size, comp_time, decomp_time, coeff):

        self.figure = plt.figure()
        self.figure0 = plt.figure()
        self.canvas = FigureCanvas(self.figure)
        self.canvas_0 = FigureCanvas(self.figure0)
        self.ui.verticalLayout.addWidget(self.canvas)
        self.ui.verticalLayout.addWidget(self.canvas_0)

        size_names = list(size.keys())
        size_values = list(size.values())

        comp_time_names = list(comp_time.keys())
        comp_time_values = list(comp_time.values())

        decomp_time_names = list(decomp_time.keys())
        decomp_time_values = list(decomp_time.values())

        coeff_names = list(coeff.keys())
        coeff_values = list(coeff.values())

        width = 0.6
        axs = self.figure.subplots(1,
                                   2,
                                   gridspec_kw={
                                       'wspace': 0.3,
                                       'right': 0.97
                                   })
        rects1 = axs[0].bar(size_names, size_values, color='red', width=width)
        axs[0].set_title('Compressed Sizes')
        axs[0].set_ylabel('Size, Kb')
        rects2 = axs[1].bar(coeff_names,
                            coeff_values,
                            color='green',
                            width=width)
        axs[1].set_title('Compression Ratio')

        axs0 = self.figure0.subplots(1,
                                     2,
                                     gridspec_kw={
                                         'wspace': 0.3,
                                         'right': 0.97
                                     })
        rects0_1 = axs0[0].bar(comp_time_names,
                               comp_time_values,
                               color='blue',
                               width=width)
        axs0[0].set_title('Compressing')
        axs0[0].set_ylabel('Time, sec')
        rects0_2 = axs0[1].bar(decomp_time_names,
                               decomp_time_values,
                               color='yellow',
                               width=width)
        axs0[1].set_title('Decompressing')
        self.figure0.suptitle('Time')

        self.autolabel(rects1, axs[0], 90)
        self.autolabel(rects2, axs[1], 90)

        self.autolabel(rects0_1, axs0[0], 90)
        self.autolabel(rects0_2, axs0[1], 90)

        self.canvas.draw()
        self.canvas_0.draw()

    def clear_table(self):

        self.ui.tableWidget.clear()
        self.ui.tableWidget.setRowCount(3)
        self.ui.tableWidget.setColumnCount(6)
        self.ui.tableWidget.setHorizontalHeaderLabels(
            ('Uncompressed', 'Compressed', 'Compression Ratio',
             'Compression Time', 'Decompression Time', ' Size Percentage '))

        self.ui.tableWidget.setVerticalHeaderLabels(('LZW', 'LZ77', 'LZ78'))

        self.ui.tableWidget.resizeColumnsToContents()

    def clear_graphs(self):
        for i in reversed(range(self.ui.verticalLayout.count())):
            widgetToRemove = self.ui.verticalLayout.itemAt(i).widget()
            self.ui.verticalLayout.removeWidget(widgetToRemove)
            widgetToRemove.setParent(None)

    def analise_click(self):

        self.ui.infoLabel.setText('')
        file = self.input_file_name.replace('Compressor', '')
        self.clear_graphs()
        self.ui.checkBoxW.setChecked(True)
        self.ui.checkBox77.setChecked(True)
        self.ui.checkBox78.setChecked(True)

        uncompressedW, compressedW, ratio_w, c_stop_time_w, percantage_w, steps_w = \
            self.compressW(self.ui.textEdit.toPlainText(), self.ui.spinBox_LZW.value(), self.output_file_name)
        _, _, _, d_stop_time_w, _ = self.decompressW(
            self.input_file_name + '.lzw', self.ui.spinBox_LZW.value())
        self.ui.listWidget.clear()
        self.show_one_table_row([
            uncompressedW, compressedW, ratio_w, c_stop_time_w, d_stop_time_w,
            percantage_w
        ], 0)
        self.show_steps(steps_w, 1)

        uncompressed77, compressed77, ratio_77, c_stop_time_77, percantage_77, steps_77 = \
            self.compress77(self.ui.textEdit.toPlainText(), self.ui.spinBox_LZ77.value(), self.output_file_name)
        _, _, _, d_stop_time_77, _ = self.decompress77(
            self.input_file_name + '.lz77', self.ui.spinBox_LZ77.value())
        self.ui.listWidget.clear()
        self.show_one_table_row([
            uncompressed77, compressed77, ratio_77, c_stop_time_77,
            d_stop_time_77, percantage_77
        ], 1)
        self.show_steps(steps_w, 1)
        self.ui.listWidget_2.clear()
        self.show_steps(steps_77, 2)

        uncompressed78, compressed78, ratio_78, c_stop_time_78, percantage_78, steps_78 = \
            self.compress78(self.ui.textEdit.toPlainText(), self.output_file_name)
        _, _, _, d_stop_time_78, _ = self.decompress78(self.input_file_name +
                                                       '.lz78')
        self.ui.listWidget_3.clear()
        self.show_one_table_row([
            uncompressed78, compressed78, ratio_78, c_stop_time_78,
            d_stop_time_78, percantage_78
        ], 2)
        self.show_steps(steps_78, 3)

        sizes = {
            'Default': round(os.path.getsize(file + '.txt') / 1024, 1),
            'LZW': round(compressedW / 1024, 1),
            'LZ77': round(compressed77 / 1024, 1),
            'LZ78': round(compressed78 / 1024, 1)
        }
        comp_times = {
            'LZW': round(c_stop_time_w, 1),
            'LZ77': round(c_stop_time_77, 1),
            'LZ78': round(c_stop_time_78, 1)
        }
        decomp_times = {
            'LZW': round(d_stop_time_w, 1),
            'LZ77': round(d_stop_time_77, 1),
            'LZ78': round(d_stop_time_78, 1)
        }
        coeff = {
            'LZW': round(ratio_w, 1),
            'LZ77': round(ratio_77, 1),
            'LZ78': round(ratio_78, 1)
        }

        self.show_graphs(sizes, comp_times, decomp_times, coeff)
        self.ui.tableWidget.resizeColumnsToContents()

    def show_one_table_row(self, data, row):

        i = 0
        data[-1] = round(data[-1], 10)
        for item in data:
            cellinfo = QTableWidgetItem(str(item))
            cellinfo.setFlags(QtCore.Qt.ItemIsSelectable
                              | QtCore.Qt.ItemIsEnabled)
            self.ui.tableWidget.setItem(row, i, cellinfo)
            i += 1

    def show_steps(self, data, number):

        if number == 1:
            for step in data:
                item = QtWidgets.QListWidgetItem()
                item.setText(
                    str(step[0]) + ': <' + str(step[1]) + ', ' + str(step[2]) +
                    '>')
                item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable
                              | QtCore.Qt.ItemIsSelectable
                              | Qt.ItemIsDragEnabled)
                self.ui.listWidget.addItem(item)
        elif number == 2:
            for step in data:
                item = QtWidgets.QListWidgetItem()
                item.setText('<' + str(step[0]) + ', ' + str(step[1]) + ', ' +
                             str(step[2]) + '>')
                item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable
                              | QtCore.Qt.ItemIsSelectable
                              | Qt.ItemIsDragEnabled)
                self.ui.listWidget_2.addItem(item)
        else:
            for step in data:
                item = QtWidgets.QListWidgetItem()
                item.setText(str(step[0]) + ': <' + str(step[1]) + '>')
                item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable
                              | QtCore.Qt.ItemIsSelectable
                              | Qt.ItemIsDragEnabled)
                self.ui.listWidget_3.addItem(item)

    def compress_btn_click(self):

        self.ui.infoLabel.setText('')
        try:
            self.clear_graphs()
            self.clear_table()
            self.ui.listWidget.clear()
            self.ui.listWidget_3.clear()
            self.ui.listWidget_2.clear()

            if self.ui.checkBoxW.isChecked():
                data_w = self.compressW(self.ui.textEdit.toPlainText(),
                                        self.ui.spinBox_LZW.value(),
                                        self.output_file_name)
                new_data = list(data_w)
                new_data.insert(4, '- ' * 15)
                self.show_steps(new_data[6], 1)
                self.show_one_graph(data_w[0], data_w[1])
                self.show_one_table_row(new_data[:6], 0)
            if self.ui.checkBox77.isChecked():
                data_77 = self.compress77(self.ui.textEdit.toPlainText(),
                                          self.ui.spinBox_LZ77.value(),
                                          self.output_file_name)
                new_data = list(data_77)
                new_data.insert(4, '- ' * 15)
                self.show_steps(new_data[6], 2)
                self.show_one_graph(data_77[0], data_77[1])
                self.show_one_table_row(new_data[:6], 1)
            if self.ui.checkBox78.isChecked():
                data_78 = self.compress78(self.ui.textEdit.toPlainText(),
                                          self.output_file_name)
                new_data = list(data_78)
                new_data.insert(4, '- ' * 15)
                self.show_steps(new_data[6], 3)
                self.show_one_graph(data_78[0], data_78[1])
                self.show_one_table_row(new_data[:6], 2)

            if not self.ui.checkBoxW.isChecked(
            ) and not self.ui.checkBox77.isChecked(
            ) and not self.ui.checkBox78.isChecked():
                self.ui.infoLabel.setText(
                    'None of algorithms is chosen\nChose one of the algorithm to continue!'
                )

            self.ui.tableWidget.resizeColumnsToContents()
        except:
            self.ui.infoLabel.setText(
                'Something went wrong...\nCheck settings and try again!')

    def decompress_btn_click(self):

        self.ui.infoLabel.setText('')
        try:
            self.clear_graphs()
            self.clear_table()
            self.ui.listWidget.clear()
            self.ui.listWidget_3.clear()
            self.ui.listWidget_2.clear()

            if self.ui.checkBoxW.isChecked():
                data_w = self.decompressW(self.input_file_name,
                                          self.ui.spinBox_LZW.value())
                new_list = list(data_w)
                new_list.insert(3, '- ' * 15)
                self.show_one_graph(data_w[0], data_w[1])
                self.show_one_table_row(new_list, 0)
            if self.ui.checkBox78.isChecked():
                data_78 = self.decompress78(self.input_file_name)
                new_list = list(data_78)
                new_list.insert(3, '- ' * 15)
                self.show_one_graph(data_78[0], data_78[1])
                self.show_one_table_row(new_list, 2)
            if self.ui.checkBox77.isChecked():
                data_77 = self.decompress77(self.input_file_name,
                                            self.ui.spinBox_LZ77.value())
                new_list = list(data_77)
                new_list.insert(3, '- ' * 15)
                self.show_one_graph(data_77[0], data_77[1])
                self.show_one_table_row(new_list, 1)

            if not self.ui.checkBoxW.isChecked(
            ) and not self.ui.checkBox77.isChecked(
            ) and not self.ui.checkBox78.isChecked():
                self.ui.infoLabel.setText(
                    'None of algorithms is chosen\nChose one of the algorithm to continue!'
                )

            self.ui.tableWidget.resizeColumnsToContents()
        except:
            self.ui.infoLabel.setText(
                'Something went wrong...\nCheck settings and try again!')

    def file_btn_click(self):

        self.ui.infoLabel.setText('')
        self.ui.checkBoxW.setChecked(False)
        self.ui.checkBox78.setChecked(False)
        self.ui.checkBox77.setChecked(False)
        try:
            file_name = self.openFileNameDialog()
            if file_name[-4:] == '.lzw':
                self.ui.textEdit.setText('Decompress: ' + file_name)
                self.ui.checkBoxW.setChecked(True)
                self.input_file_name = file_name
            elif file_name[-5:] == '.lz77':
                self.ui.textEdit.setText('Decompress: ' + file_name)
                self.ui.checkBox77.setChecked(True)
                self.input_file_name = file_name
            elif file_name[-5:] == '.lz78':
                self.ui.checkBox78.setChecked(True)
                self.input_file_name = file_name
                self.ui.textEdit.setText('Decompress: ' + file_name)
            else:
                try:
                    with open(file_name, 'r') as file:
                        self.ui.textEdit.setText(file.read())
                except:
                    with open(file_name, 'r', encoding='utf-8') as file:
                        self.ui.textEdit.setText(file.read())
        except:
            file_name = ''

    def openFileNameDialog(self):

        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(
            self,
            "Choose File",
            "",
            "All Files (*);;Python Files (*.py)",
            options=options)
        if fileName:
            self.output_file_name = fileName.replace('.txt', '').replace(
                '.lzw', '').replace('.lz78', '').replace('.lz77', '').replace(
                    'Compressor', '') + 'Compressor'
            self.ui.outEdit.setText(self.output_file_name)
            self.input_file_name = fileName.replace('.txt', '') + 'Compressor'
            return fileName

    def saveFileDialog(self):

        self.ui.infoLabel.setText('')
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        dirName = QFileDialog.getExistingDirectory(self,
                                                   "Choose directory",
                                                   options=options)
        if dirName:
            if self.input_file_name:
                self.output_file_name = dirName + '/' + self.input_file_name
            else:
                self.output_file_name = dirName + '/Compressor'
            self.ui.outEdit.setText(self.output_file_name)

    def LZ77_search(self, search, look_ahead):

        ls = len(search)
        llh = len(look_ahead)

        if (ls == 0):
            return (0, 0, look_ahead[0])
        if (llh) == 0:
            return (-1, -1, "")

        best_length = 0
        best_offset = 0
        buf = search + look_ahead

        search_pointer = ls
        for i in range(0, ls):
            length = 0
            while buf[i + length] == buf[search_pointer + length]:
                length = length + 1
                if search_pointer + length == len(buf):
                    length = length - 1
                    break
                if i + length >= search_pointer:
                    break
            if length > best_length:
                best_offset = i
                best_length = length

        return (best_offset, best_length, buf[search_pointer + best_length])

    def compress77(self, input, win_size, output_file):
        start_time = time.time()
        #extra credit
        x = 16
        MAXSEARCH = int(win_size)
        MAXLH = int(math.pow(2, (x - (math.log(MAXSEARCH, 2)))))
        file = open(output_file + '.lz77', "wb")
        searchiterator, lhiterator = 0, 0
        steps = []
        while lhiterator < len(input):
            search = input[searchiterator:lhiterator]
            look_ahead = input[lhiterator:lhiterator + MAXLH]
            (offset, length, char) = self.LZ77_search(search, look_ahead)
            steps.append([offset, length, char])
            shifted_offset = offset << 6
            offset_and_length = shifted_offset + length
            placeholder = ' '
            try:
                ol_bytes = pack(">Hc", offset_and_length, bytes(char, 'utf-8'))
            except:
                ol_bytes = pack(">Hc", offset_and_length,
                                bytes(placeholder, 'utf-8'))
            file.write(ol_bytes)

            lhiterator = lhiterator + length + 1
            searchiterator = lhiterator - MAXSEARCH

            if searchiterator < 0:
                searchiterator = 0

        file.close()

        return os.path.getsize(output_file.replace('Compressor', '') + '.txt'), \
               os.path.getsize(output_file + '.lz77'), os.path.getsize(output_file.replace('Compressor', '') + '.txt')/\
               os.path.getsize(output_file + '.lz77'), time.time() - start_time, os.path.getsize(output_file + '.lz77')/\
               os.path.getsize(output_file.replace('Compressor', '') + '.txt')*100, steps

    def decompress77(self, input_file, search):

        start_time = time.time()
        try:
            processed = open(self.output_file_name + 'LZ77.txt', "wb")
        except:
            processed = open(self.output_file_name + 'LZ77.txt',
                             "wb",
                             encoding='utf-8')

        MAX_SEARCH = search
        file = open(input_file, "rb")
        input = file.read()
        chararray = bytearray()
        i = 0

        while i < len(input):
            (offset_and_length, char) = unpack(">Hc", input[i:i + 3])
            offset = offset_and_length >> 6
            length = offset_and_length - (offset << 6)
            i = i + 3
            if (offset == 0) and (length == 0):
                chararray += char
            else:
                iterator = len(chararray) - MAX_SEARCH
                if iterator < 0:
                    iterator = offset
                else:
                    iterator += offset
                for pointer in range(length):
                    chararray += bytes(chr(chararray[iterator + pointer]),
                                       'utf-8')
                chararray += char
        processed.write(chararray)

        return os.path.getsize(self.output_file_name + 'LZ77.txt'), \
               os.path.getsize(input_file), os.path.getsize(self.output_file_name + 'LZ77.txt')/\
               os.path.getsize(input_file), time.time() - start_time, os.path.getsize(input_file)/\
               os.path.getsize(self.output_file_name + 'LZ77.txt')*100

    def compressW(self, data, dictionary_size, output_file):

        start_time = time.time()
        n = 256
        maximum_table_size = pow(2, int(n))
        data = data.replace('—', '-').replace('…', '...').replace('–', '-')\
                .replace('№', '!n').replace('’', '\'').replace('‘', '\'').replace('“', '\'')\
                .replace('”', '\'').replace('„', '\'')

        dictionary = {chr(i): i for i in range(dictionary_size)}
        string = ""
        compressed_data = []
        steps = []
        for symbol in data:
            string_plus_symbol = string + symbol
            if string_plus_symbol in dictionary:
                string = string_plus_symbol
            else:
                compressed_data.append(dictionary[string])
                if (len(dictionary) <= maximum_table_size):
                    dictionary[string_plus_symbol] = dictionary_size
                    dictionary_size += 1
                string = symbol
            try:
                steps.append([symbol, string, dictionary[string]])
            except:
                string = ' '
                steps.append([symbol, string, dictionary[string]])

        if string in dictionary:
            compressed_data.append(dictionary[string])
        out_file = open(output_file + ".lzw", "wb")
        for data in compressed_data:
            out_file.write(pack('>L', int(data)))
        out_file.close()
        print(output_file)

        return os.path.getsize(output_file.replace('Compressor', '') + '.txt'), \
               os.path.getsize(output_file + '.lzw'), os.path.getsize(output_file.replace('Compressor', '') + '.txt')/\
               os.path.getsize(output_file + '.lzw'), time.time() - start_time, os.path.getsize(output_file + '.lzw')/\
               os.path.getsize(output_file.replace('Compressor', '') + '.txt')*100, steps

    def decompressW(self, input_file, dictionary_size):

        start_time = time.time()
        compressed_data = []
        file = open(input_file, "rb")
        while True:
            rec = file.read(4)
            if len(rec) != 4:
                break
            (data, ) = unpack('>L', rec)
            compressed_data.append(data)
            compressed = compressed_data

        dictionary = dict([(x, chr(x)) for x in range(dictionary_size)])

        result = StringIO()
        w = chr(compressed.pop(0))
        result.write(w)
        for k in compressed:
            if k in dictionary:
                entry = dictionary[k]
            elif k == dictionary_size:
                entry = w + w[0]
            else:
                raise ValueError('Bad compressed k: %s' % k)
            result.write(entry)
            dictionary[dictionary_size] = w + entry[0]
            dictionary_size += 1

            w = entry
        write_file = open(self.output_file_name + 'LZW.txt',
                          'w',
                          encoding='ANSI')
        write_file.write(result.getvalue())

        return os.path.getsize(self.output_file_name + 'LZW.txt'), \
               os.path.getsize(input_file), os.path.getsize(self.output_file_name + 'LZW.txt')/\
               os.path.getsize(input_file), time.time() - start_time, os.path.getsize(input_file)/\
               os.path.getsize(self.output_file_name + 'LZW.txt')*100

    def compress78(self, data, output_file):

        start_time = time.time()
        encoded_file = open(output_file + '.lz78', 'wb')
        text_from_file = data
        text_from_file = text_from_file.replace('1', '!a').replace('2', '!b').replace('3', '!c')\
            .replace('4', '!d').replace('5', '!e').replace('6', '!f')\
            .replace('7', '!g').replace('8', '!h').replace('9', '!i').replace('0', '!g').replace('…', '')\
            .replace('–', '-').replace('№', '!n').replace('’', '\'').replace('‘', '\'').replace('“', '\'')\
            .replace('”', '\'').replace('„', '\'').replace('«', '\'').replace('»', '\'').replace('°', '\'')
        dict_of_codes = {text_from_file[0]: '1'}
        encoded_file.write(pack('>Ic', 0, bytes(text_from_file[0], 'utf-8')))
        text_from_file = text_from_file[1:]
        combination = ''
        code = 2
        result = ''
        steps = []
        for char in text_from_file:
            combination += char
            if combination not in dict_of_codes:
                dict_of_codes[combination] = str(code)
                if len(combination) == 1:
                    step = '0' + combination
                    step_num = 0
                    encoded_file.write(pack('>Ic', 0, bytes(char, 'utf-8')))
                    result += step
                else:
                    step = dict_of_codes[combination[0:-1]] + combination[-1]
                    step_num = int(dict_of_codes[combination[0:-1]])
                    encoded_file.write(
                        pack('>Ic', step_num, bytes(char, 'utf-8')))
                    result += step
                code += 1
                combination = ''
                steps.append([char, step])
        encoded_file.close()

        return os.path.getsize(output_file.replace('Compressor', '') + '.txt'), \
               os.path.getsize(output_file + '.lz78'), os.path.getsize(output_file.replace('Compressor', '') + '.txt')/\
               os.path.getsize(output_file + '.lz78'), time.time() - start_time, os.path.getsize(output_file + '.lz78')/\
               os.path.getsize(output_file.replace('Compressor', '') + '.txt')*100, steps

    def decompress78(self, input_file):

        start_time = time.time()
        output_file = self.output_file_name
        try:
            decoded_file = open(output_file + 'LZ78.txt',
                                'w',
                                encoding='utf=8')
        except:
            decoded_file = open(output_file + 'LZ78.txt', 'w')

        file = open(input_file, "rb")
        input = file.read()
        text_from_file = ''
        i = 0
        while i < len(input):
            (num, char) = unpack(">Ic", input[i:i + 5])
            i = i + 5
            text_from_file += str(num) + char.decode()
        dict_of_codes = {'0': '', '1': text_from_file[1]}
        decoded_file.write(dict_of_codes['1'])
        text_from_file = text_from_file[2:]
        combination = ''
        code = 2
        decoded_text = ''
        for char in text_from_file:
            if char in '1234567890':
                combination += char
            else:
                dict_of_codes[str(code)] = dict_of_codes[combination] + char
                decoded_text += dict_of_codes[combination] + char
                combination = ''
                code += 1
        decoded_text = decoded_text.replace('!a', '1').replace('!b', '2').replace('!c', '3')\
            .replace('!d', '4').replace('!e', '5').replace('!f', '6')\
            .replace('!g', '7').replace('!h', '8').replace('!i', '9').replace('!g', '0')
        decoded_file.write(decoded_text)
        decoded_file.close()

        return os.path.getsize(self.output_file_name + 'LZ78.txt'), \
               os.path.getsize(input_file), os.path.getsize(self.output_file_name + 'LZ78.txt')/\
               os.path.getsize(input_file), time.time() - start_time, os.path.getsize(input_file)/\
               os.path.getsize(self.output_file_name + 'LZ78.txt')*100
class Window(QDialog):
#    https://stackoverflow.com/questions/12459811/how-to-embed-matplotlib-in-pyqt-for-dummies
    
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        # a figure instance to plot on
        self.figure = plt.figure()

        # this is the Canvas Widget that displays the `figure`
        # it takes the `figure` instance as a parameter to __init__
        self.canvas = FigureCanvas(self.figure)

        # this is the Navigation widget
        # it takes the Canvas widget and a parent
        self.toolbar = NavigationToolbar(self.canvas, self)

        # Just some button connected to `plot` method
        self.button1 = QPushButton('Plot')
        self.button1.clicked.connect(self.plot)

        # Just some button connected to `imshow` method
        self.button2 = QPushButton('Imshow')
        self.button2.clicked.connect(self.imshow)

        # set the layout
        layout = QVBoxLayout()
#        layout.addWidget(self.toolbar)
        layout.addWidget(self.canvas)
        layout.addWidget(self.button1)
        layout.addWidget(self.button2)
        self.setLayout(layout)
        
        self.num = 10

    def plot(self):
        ''' plot some random stuff '''
        
        print("plot...")
        
        # random data
        data = [random.random() for i in range(self.num)]

        # instead of ax.hold(False)
        self.figure.clear()

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

        # discards the old graph
        # ax.hold(False) # deprecated, see above

        # plot data
#        ax.imshow(hbt.dist(self.num))
        ax.plot(data, '*-')

        # refresh canvas
        self.canvas.draw()

    def imshow(self):
        ''' plot some random stuff '''

        print('Imshow...')
        # instead of ax.hold(False)
        self.figure.clear()

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

        # plot data
        ax.imshow(hbt.dist(self.num))
#        ax.plot(data, '*-')

        # refresh canvas
        self.canvas.draw()

    def keyPressEvent(self, event):
        
        # http://zetcode.com/gui/pyqt5/eventssignals/
      print ("Key hit: {}".format(event.key()))
      
      if event.key() == Qt.Key_Escape:
         self.close()
      if event.key() == Qt.Key_Left:
          self.num -= 1
          self.plot()
      if event.key() == Qt.Key_Right:
          self.num += 1
          self.plot()
Beispiel #52
0
class GraphTab(QWidget):
    def __init__(self, parent=None, tabs=None, tab_name="Graph Tab"):
        super(GraphTab, self).__init__(parent)
        logger.debug("Setting up Graph Tab.")
        self.root = parent
        self.tabs = tabs
        self.tab_name = tab_name
        self.data_list = []
        self.init_ui()

    def init_ui(self):
        self.graph_tab = QWidget()
        self.tabs.addTab(self.graph_tab, self.tab_name)
        logger.debug("Making Attribution Box")
        attribution_box = QGroupBox("Event Attribution Data")
        tab_layout = QGridLayout()
        self.graph_tab.setLayout(tab_layout)

        self.event_name_label = QLabel("Name of Event: ")
        self.ecm_rtc_label = QLabel("ECM Real Time Clock at Event: ")
        self.actual_rtc_label = QLabel("Actual Real Time Clock at Event: ")
        self.engine_hours_label = QLabel("Engine Hours at Event: ")
        self.odometer_label = QLabel("Distance Reading at Event: ")

        attribution_layout = QVBoxLayout()
        attribution_layout.addWidget(self.event_name_label)
        attribution_layout.addWidget(self.ecm_rtc_label)
        attribution_layout.addWidget(self.actual_rtc_label)
        attribution_layout.addWidget(self.engine_hours_label)
        attribution_layout.addWidget(self.odometer_label)
        attribution_box.setLayout(attribution_layout)
        logger.debug("Finished Setting Attribution Layout")

        self.data_table = QTableWidget()
        self.data_table.setSelectionBehavior(QAbstractItemView.SelectColumns)
        logger.debug("Finished with Data Table")

        self.csv_button = QPushButton("Export CSV")
        self.csv_button.clicked.connect(self.export_csv)
        logger.debug("Finished with CSV")

        self.figure = mpl.Figure(figsize=(7, 9))
        self.canvas = FigureCanvas(self.figure)
        self.top_axis = self.figure.add_subplot(3, 1, 1)
        self.top_axis.set_ylabel("Road Speed (mph)")
        self.middle_axis = self.figure.add_subplot(3, 1, 2)
        self.middle_axis.set_ylabel("Throttle Position (%)")
        self.bottom_axis = self.figure.add_subplot(3, 1, 3)
        self.bottom_axis.set_ylabel("Brake Switch Status")
        self.bottom_axis.set_xlabel("Event Time (sec)")
        self.canvas.draw()

        self.toolbar = NavigationToolbar(self.canvas, self.graph_tab)
        logger.debug("Finished with toolbar")

        # set the layout

        tab_layout.addWidget(attribution_box, 0, 0, 1, 1)
        tab_layout.addWidget(self.data_table, 1, 0, 1, 1)
        tab_layout.addWidget(self.csv_button, 2, 0, 1, 1)
        tab_layout.addWidget(self.canvas, 0, 1, 2, 1)
        tab_layout.addWidget(self.toolbar, 2, 1, 1, 1)

        logger.debug("Finished with UI for Tab {}".format(self.tab_name))

    def export_csv(self):
        logger.debug("Export CSV")
        filters = "Comma Separated Values (*.csv);;All Files (*.*)"
        selected_filter = "Comma Separated Values (*.csv)"
        fname = QFileDialog.getSaveFileName(self, 'Export CSV',
                                            self.tab_name + ".csv", filters,
                                            selected_filter)
        if fname[0]:
            if fname[0][-4:] == ".csv":
                filename = fname[0]
            else:
                filename = fname[0] + ".csv"
            try:
                with open(filename, 'w', newline='') as csv_file:
                    writer = csv.writer(csv_file)
                    writer.writerow(["The University of Tulsa"])

                    writer.writerow([
                        "Date of Creation:",
                        "{}".format(get_local_time_string(time.time()))
                    ])

                    writer.writerows(['', ["Vehicle Component Information"]])
                    writer.writerows(
                        get_list_from_dict(
                            self.root.data_package["Component Information"]))

                    writer.writerows(['', ["Vehicle Distance Information"]])
                    writer.writerows(
                        get_list_from_dict(
                            self.root.data_package["Distance Information"]))

                    writer.writerows(['', ["Vehicle Time Information"]])
                    writer.writerows(
                        get_list_from_dict(
                            self.root.data_package["ECU Time Information"]))

                    writer.writerows(['', ["Event Attribution Data"]])
                    writer.writerow([''] +
                                    self.event_name_label.text().split(": "))
                    writer.writerow([''] +
                                    self.ecm_rtc_label.text().split(": "))
                    writer.writerow([''] +
                                    self.actual_rtc_label.text().split(": "))
                    writer.writerow([''] +
                                    self.engine_hours_label.text().split(": "))
                    writer.writerow([''] +
                                    self.odometer_label.text().split(": "))
                    writer.writerows(['', ["Event Table Data"]])
                    writer.writerows(self.data_list)

                    writer.writerows(['', ["User Data"]])
                    writer.writerows(self.root.user_data.get_user_data_list())
                self.root.sign_file(filename)
                base_name = os.path.basename(filename)
                QMessageBox.information(
                    self, "Export Success",
                    "The comma separated values file\n{}\nwas successfully exported. A verification signature was also saved as\n{}."
                    .format(base_name, base_name + ".signature"))

            except PermissionError:
                logger.info(
                    "Permission Error - Please close the file and try again.")
                QMessageBox.warning(
                    self, "Permission Error",
                    "Permission Error\nThe file may be open in another application.\nPlease close the file and try again."
                )

    def update_plot_xy(self):
        for key, value in self.data.items():
            self.ax.plot(value["X"], value["Y"], value["Marker"], label=key)
        self.ax.grid(True)
        self.ax.legend()
        [xmin, xmax, ymin, ymax] = self.ax.axis()
        try:
            self.ax.axis([xmin, xmax, self.ymin, self.ymax])
        except:
            pass
        self.ax.set_xlabel(self.x_label)
        self.ax.set_ylabel(self.y_label)
        self.ax.set_title(self.title)
        if self.update_button.isChecked():
            self.canvas.draw()
Beispiel #53
0
class RoastGraphWidget():
    def __init__(self, graphXValueList=None, graphYValueList=None, 
            animated=False, updateMethod=None, animatingMethod=None):

        self.graphXValueList = graphXValueList or []
        self.graphYValueList = graphYValueList or []
        self.counter = 0
        self.updateMethod = updateMethod
        self.animated = animated
        # Check if graph should continue to graph.
        self.animatingMethod = animatingMethod

        self.widget = self.create_graph()

    def create_graph(self):
        # Create the graph widget.
        graphWidget = QtWidgets.QWidget()
        graphWidget.setObjectName("graph")

        # Style attributes of matplotlib.
        plt.rcParams['lines.linewidth'] = 3
        plt.rcParams['lines.color'] = '#2a2a2a'
        plt.rcParams['font.size'] = 10.

        self.graphFigure = plt.figure(facecolor='#444952')
        self.graphCanvas = FigureCanvas(self.graphFigure)

        # Add graph widgets to layout for graph.
        graphVerticalBox = QtWidgets.QVBoxLayout()
        graphVerticalBox.addWidget(self.graphCanvas)
        graphWidget.setLayout(graphVerticalBox)

        # Animate the the graph with new data
        if self.animated:
            animateGraph = animation.FuncAnimation(self.graphFigure,
                self.graph_draw, interval=1000)
        else:
            self.graph_draw()

        return graphWidget

    def graph_draw(self, *args, **kwargs):
        # Start graphing the roast if the roast has started.
        if self.animatingMethod is not None:
            if self.animatingMethod():
                self.updateMethod()

        self.graphFigure.clear()

        self.graphAxes = self.graphFigure.add_subplot(111)
        self.graphAxes.plot_date(self.graphXValueList, self.graphYValueList,
            '#8ab71b')

        # Add formatting to the graphs.
        self.graphAxes.set_ylabel('TEMPERATURE (°F)')
        self.graphAxes.set_xlabel('TIME')
        self.graphFigure.subplots_adjust(bottom=0.2)

        ax = self.graphAxes.get_axes()
        ax.xaxis.set_major_formatter(DateFormatter('%M:%S'))
        ax.set_axis_bgcolor('#23252a')

        self.graphCanvas.draw()

    def append_x(self, xCoord):
        self.counter += 1
        currentTime = datetime.datetime.fromtimestamp(self.counter)
        self.graphXValueList.append(matplotlib.dates.date2num(currentTime))
        self.graphYValueList.append(xCoord)

    def clear_graph(self):
        self.graphXValueList = []
        self.graphYValueList = []
        self.counter = 0
        self.graphFigure.clear()

    def save_roast_graph(self):
        try:
            file_name = QtWidgets.QFileDialog.getSaveFileName(
                QtWidgets.QWidget(), 
                'Save Roast Graph', 
                os.path.expanduser('~/'), 
                'Graph (*.png);;All Files (*)')
            self.graphFigure.savefig(file_name[0], bbox_inches='tight')
        except FileNotFoundError:
            # Occurs if file browser is canceled
            pass
        else:
            pass
Beispiel #54
0
class GraphDialog(QDialog):
    def __init__(self, parent=None, title="Graph"):
        super(GraphDialog, self).__init__(parent)
        self.setWindowTitle(title)
        self.figure = mpl.Figure()
        self.canvas = FigureCanvas(self.figure)
        self.toolbar = NavigationToolbar(self.canvas, self)
        self.data = {}

        self.ax = self.figure.add_subplot(111)
        self.ymin = None
        self.ymax = None
        self.x_label = ""
        self.y_label = ""
        self.title = ""

        self.update_button = QCheckBox("Dynamically Update Table")
        self.update_button.setChecked(True)

        # set the layout
        layout = QVBoxLayout()
        layout.addWidget(self.canvas)
        layout.addWidget(self.update_button)
        layout.addWidget(self.toolbar)
        self.setLayout(layout)
        #self.show()

    def plot(self):
        ''' plot data '''
        self.ax.cla()
        #self.ax.hold(False)
        for key, value in self.data.items():
            self.ax.plot(value["X"], value["Y"], value["Marker"], label=key)
        self.ax.grid(True)
        self.ax.legend()
        [xmin, xmax, ymin, ymax] = self.ax.axis()
        try:
            self.ax.axis([xmin, xmax, self.ymin, self.ymax])
        except:
            pass
        xfmt = md.DateFormatter('%Y-%m-%d %H:%M:%S')
        self.ax.xaxis.set_major_formatter(xfmt)
        self.figure.autofmt_xdate()
        self.ax.set_xlabel(self.x_label)
        self.ax.set_ylabel(self.y_label)
        self.ax.set_title(self.title)
        if self.update_button.isChecked():
            self.canvas.draw()

    def plot_xy(self):
        self.ax.cla()
        #self.ax.hold(False)
        for key, value in self.data.items():
            self.ax.plot(value["X"], value["Y"], value["Marker"], label=key)
        self.ax.grid(True)
        self.ax.legend()
        [xmin, xmax, ymin, ymax] = self.ax.axis()
        try:
            self.ax.axis([xmin, xmax, self.ymin, self.ymax])
        except:
            pass
        self.ax.set_xlabel(self.x_label)
        self.ax.set_ylabel(self.y_label)
        self.ax.set_title(self.title)
        if self.update_button.isChecked():
            self.canvas.draw()

    def add_data(self, data, marker='*-', label=""):
        x, y = zip(*data)  #unpacks a list of tuples
        dates = [dt.datetime.fromtimestamp(ts) for ts in x]
        self.data[label] = {"X": dates, "Y": y, "Marker": marker}

    def add_xy_data(self, data, marker='*-', label=""):
        x, y = zip(*data)  #unpacks a list of tuples
        # logger.debug("X data:")
        # logger.debug(x)
        # logger.debug("Y data:")
        # logger.debug(y)

        self.data[label] = {
            "X": [float(val) for val in x],
            "Y": [float(val) for val in y],
            "Marker": marker
        }

    def set_yrange(self, min_y, max_y):
        self.ymax = max_y
        self.ymin = min_y

    def set_xlabel(self, label):
        self.x_label = label

    def set_ylabel(self, label):
        self.y_label = label

    def set_title(self, label):
        self.title = label
Beispiel #55
0
class Window(QDialog):
    def __init__(self, params_object, compound_object, library_object, editable=False, parent=None):
        QDialog.__init__(self, parent)
        self.params = params_object
        self.compound = compound_object
        self.library = library_object
        self.editable = editable
        self.modified = False
        self.setWindowTitle("NMRmix: Information for Compound %s" % self.compound.id)
        self.createWidgets()
        self.layoutWidgets()
        self.createConnections()
        self.drawData()
        self.setTable()

    def createWidgets(self):
        self.compoundTabs = QTabWidget()
        self.compoundTabs.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding)
        self.compoundTabs.setStyleSheet('QTabBar {font-weight: bold;}'
                                     'QTabBar::tab {color: black;}'
                                     'QTabBar::tab:selected {color: red;}')
        self.initInfo()
        self.initSpectrum()
        self.initPeaklistTable()

    def initInfo(self):
        # Compound Info Tab
        self.compoundtab1 = QWidget()
        self.compoundtab1.setStyleSheet("QWidget{background-color: white;}")
        self.idLabel = QLabel("<h2><font color='red'>%s</font></h2>" % self.compound.id)
        self.idLabel.setAlignment(Qt.AlignCenter)
        self.nameLabel = QLabel("<b>Name:</b> %s" % self.compound.name)
        self.groupLabel = QLabel("<b>Group:</b> %s" % self.compound.group)
        self.bmrbLabel = QLabel("<b>BMRB ID:</b> %s" % self.compound.bmrb_id)
        self.bmrbLabel.setTextInteractionFlags(Qt.LinksAccessibleByMouse)
        self.bmrbLabel.setOpenExternalLinks(True)
        self.hmdbLabel = QLabel("<b>HMDB ID:</b> %s" % self.compound.hmdb_id)
        self.hmdbLabel.setTextInteractionFlags(Qt.LinksAccessibleByMouse)
        self.hmdbLabel.setOpenExternalLinks(True)
        self.pubchemLabel = QLabel("<b>PubChem CID:</b> <a href='https://pubchem.ncbi.nlm.nih.gov/compound/%s'>%s</a>"
                                   % (self.compound.pubchem_id, self.compound.pubchem_id))
        self.pubchemLabel.setTextInteractionFlags(Qt.LinksAccessibleByMouse)
        self.pubchemLabel.setOpenExternalLinks(True)
        self.keggLabel = QLabel("<b>KEGG ID:</b> <a href='http://www.genome.jp/dbget-bin/www_bget?cpd:%s'>%s</a>"
                                % (self.compound.kegg_id, self.compound.kegg_id))
        self.keggLabel.setTextInteractionFlags(Qt.LinksAccessibleByMouse)
        self.keggLabel.setOpenExternalLinks(True)
        self.structureLabel = QLabel("<b>Structure: </b>")
        self.structure = QLabel()


        if self.compound.smiles:
            self.smilesLabel = QLabel("<b>SMILES:</b> %s" % self.compound.smiles)
            try:
                self.compound.set2DStructure()
                molformula = ""
                for count, i in enumerate(self.compound.molformula):
                    try:
                        if count > 0:
                            if self.compound.molformula[count-1] == "-" or self.compound.molformula[count-1] == "+":
                                j = "<sup>%d</sup>" % int(i)
                            else:
                                j = "<sub>%d</sub>" % int(i)
                        else:
                            j = i
                    except:
                        if i == "-" or i == "+":
                            j = "<sup>%s</sup>" % i
                        else:
                            j = i
                    molformula += j
                if self.compound.molwt and self.compound.molformula:
                    self.molformulaLabel = QLabel("<b>Mol. Formula:</b> %s" % molformula)
                    self.molwtLabel = QLabel("<b>Mol. Weight:</b> %0.3f" % self.compound.molwt)
                else:
                    self.molformulaLabel = QLabel("<b>Mol. Formula:</b> Unknown")
                    self.molwtLabel = QLabel("<b>Mol. Weight:</b> Unknown")
                if self.compound.structure_image:
                    self.pixmap = QPixmap.fromImage(self.compound.structure_qt)
                    self.structure.setText("")
                    self.structure.setPixmap(self.pixmap)
                    self.structure.setAlignment(Qt.AlignCenter)
                else:
                    self.structure.setText("No Structure Available")
                    self.structure.setAlignment(Qt.AlignCenter)
            except:
                self.molformulaLabel = QLabel("<b>Mol. Formula:</b> Unknown")
                self.molwtLabel = QLabel("<b>Mol. Weight:</b> Unknown")
                self.structure.setText("No Structure Available")
                self.structure.setAlignment(Qt.AlignCenter)

        else:
            self.smilesLabel = QLabel("<b>SMILES:</b> Unknown")
            self.molformulaLabel = QLabel("<b>Mol. Formula:</b> Unknown")
            self.molwtLabel = QLabel("<b>Mol. Weight:</b> Unknown")
            self.structure.setText("No Structure Available")
            self.structure.setAlignment(Qt.AlignCenter)

        self.editinfoButton = QPushButton('Edit Compound Info')
        self.editinfoButton.setToolTip("Opens a window to edit compound information") # TODO: Set tooltip
        self.restoreinfoButton = QPushButton('Restore Compound Info')
        self.restoreinfoButton.setToolTip("Resets compound information to original imported values") # TODO: Set tooltip
        self.savestructureButton = QPushButton('Save Structure Image')
        self.savestructureButton.setToolTip("Tooltip") # TODO: Set tooltip


    def initSpectrum(self):
        # Compound Spectrum Tab
        matplotlib.projections.register_projection(My_Axes)
        self.scale = 1.05
        self.show_ignored = True
        self.show_ignored_peaks = True
        self.compoundtab2 = QWidget()
        self.compoundtab2.setStyleSheet("QWidget{background-color: white;}")
        self.fig = plt.gcf()
        self.fig.patch.set_facecolor('white')
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self)
        self.canvas.setFocusPolicy(Qt.StrongFocus)
        self.canvas.setFocus()
        self.canvas.setMinimumHeight(100)
        self.canvas.setMinimumWidth(100)
        self.mpl_toolbar = NavigationToolbar2(self.canvas, self)
        self.mpl_toolbar.hide()
        self.mpl_toolbar.pan()
        self.canvas.mpl_connect('scroll_event', self.zooming)
        ins = "Left-click+drag to pan x-axis / Right-click+drag to zoom x-axis / Scroll-wheel to change intensity scale"
        self.instructionLabel = QLabel(ins)
        self.instructionLabel.setStyleSheet('QLabel{qproperty-alignment: AlignCenter; font-size: 10px;}')
        self.showignoredregionsCheckBox = QCheckBox("Show Ignored Regions")
        self.showignoredregionsCheckBox.setToolTip("Shows the ranges set by the solvent/buffer ignore regions, if any.")
        self.showignoredregionsCheckBox.setLayoutDirection(Qt.RightToLeft)
        self.showignoredregionsCheckBox.setChecked(True)
        self.showignoredpeaksCheckBox = QCheckBox("Show Ignored Peaks")
        self.showignoredpeaksCheckBox.setToolTip("Shows any compound peaks that are in the solvent/buffer ignore regions, if any.\n"
                                                 "These peaks are ignored and are not evaluated during mixing.")
        self.showignoredpeaksCheckBox.setLayoutDirection(Qt.RightToLeft)
        self.showignoredpeaksCheckBox.setChecked(True)
        self.resetviewButton = QPushButton("Reset View")
        self.resetviewButton.setToolTip("Resets the spectrum to the default view.")
        self.savespectrumButton = QPushButton("Save Spectrum")
        self.savespectrumButton.setToolTip("Saves the image in the spectrum window.")

    def initPeaklistTable(self):
        # Compound Peaklist Tab
        self.compoundtab3 = QWidget()
        self.compoundtab3.setStyleSheet("QWidget{background-color: white;}")
        self.peakTable = QTableWidget(0, 4, self)
        # self.peakTable.setMinimumWidth(400)
        self.peakTable.setSelectionMode(QAbstractItemView.NoSelection)
        self.peakTable.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.peakTable.setSelectionMode(QAbstractItemView.SingleSelection)
        self.peakTable.setSortingEnabled(True)
        self.peakTable.sortByColumn(1, Qt.AscendingOrder)
        self.peakTable.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.peakTable.setColumnWidth(0, 100)
        self.peakTable.setColumnWidth(1, 200)
        self.peakTable.setColumnWidth(2, 150)
        self.peakTable.setColumnWidth(3, 100)
        self.peakTable.horizontalHeader().setStretchLastSection(True)
        self.tableheader = ['Status', 'Chemical Shift', 'Intensity', 'Width']
        self.peakTable.setHorizontalHeaderLabels(self.tableheader)
        self.peakTable.horizontalHeader().setStyleSheet("QHeaderView {font-weight: bold;}")
        self.peakTable.verticalHeader().setStyleSheet("QHeaderView {font-weight: bold;}")
        self.addButton = QPushButton("Add")
        self.addButton.setToolTip("Opens a window to add a new peak to the table")

        self.editButton = QPushButton("Edit")
        self.editButton.setToolTip("Opens a window to edit the currently selected peak.")

        self.removeButton = QPushButton("Remove")
        self.removeButton.setToolTip("Inactivates the currently selected peak.")

        self.restorepeaklistButton = QPushButton("Restore")
        self.restorepeaklistButton.setToolTip("Restores the original peak list.")

        self.savepeaksButton = QPushButton("Save")
        self.savepeaksButton.setToolTip("Saves the current peak list as a custom peak list file.\n"
                                        "This file can be used as the peak list for future library imports.")
        if not self.editable:
            self.removeButton.hide()
            self.restorepeaklistButton.hide()
            self.savepeaksButton.hide()
            self.editButton.hide()
            self.addButton.hide()

        self.closeButton = QPushButton("Close")
        self.closeButton.setStyleSheet("QPushButton{color: red; font-weight:bold;}")
        self.closeButton.setFixedWidth(200)

    def layoutWidgets(self):
        winLayout = QVBoxLayout(self)

        infoLayout = QVBoxLayout(self.compoundtab1)
        infoLayout.addWidget(self.idLabel)
        infoLayout.addWidget(self.nameLabel)
        infoLayout.addWidget(self.groupLabel)
        infoLayout.addWidget(self.bmrbLabel)
        infoLayout.addWidget(self.hmdbLabel)
        infoLayout.addWidget(self.pubchemLabel)
        infoLayout.addWidget(self.keggLabel)
        infoLayout.addWidget(self.smilesLabel)
        infoLayout.addWidget(self.molformulaLabel)
        infoLayout.addWidget(self.molwtLabel)
        infoLayout.addWidget(self.structureLabel)
        infoLayout.addItem(QSpacerItem(400, 20, QSizePolicy.Maximum, QSizePolicy.Maximum))
        infoLayout.addWidget(self.structure)
        infoLayout.addItem(QSpacerItem(400, 20, QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding))
        infobuttonLayout = QHBoxLayout()
        infobuttonLayout.addWidget(self.editinfoButton)
        infobuttonLayout.addWidget(self.restoreinfoButton)
        infobuttonLayout.addWidget(self.savestructureButton)
        infoLayout.addLayout(infobuttonLayout)
        self.compoundtab1.setLayout(infoLayout)
        self.compoundTabs.addTab(self.compoundtab1, "Compound Info")

        spectraLayout = QVBoxLayout(self.compoundtab2)
        spectraLayout.addWidget(self.canvas)
        spectraLayout.addWidget(self.instructionLabel)
        spectraCheckBoxLayout = QHBoxLayout()
        spectraCheckBoxLayout.addItem(QSpacerItem(0,0, QSizePolicy.MinimumExpanding))
        spectraCheckBoxLayout.addWidget(self.showignoredregionsCheckBox)
        spectraCheckBoxLayout.addItem(QSpacerItem(15, 0, QSizePolicy.Maximum))
        spectraCheckBoxLayout.addWidget(self.showignoredpeaksCheckBox)
        spectraCheckBoxLayout.addItem(QSpacerItem(0,0, QSizePolicy.MinimumExpanding))
        spectraLayout.addLayout(spectraCheckBoxLayout)
        spectraButtonLayout = QHBoxLayout()
        spectraButtonLayout.addWidget(self.resetviewButton)
        spectraButtonLayout.addWidget(self.savespectrumButton)
        spectraLayout.addLayout(spectraButtonLayout)
        self.compoundtab2.setLayout(spectraLayout)
        self.compoundTabs.addTab(self.compoundtab2, "Simulated Spectrum")

        tableLayout = QVBoxLayout()
        tableLayout.addWidget(self.peakTable)
        tablebuttonLayout = QHBoxLayout()
        tablebuttonLayout.addWidget(self.addButton)
        tablebuttonLayout.addWidget(self.editButton)
        tablebuttonLayout.addWidget(self.removeButton)
        tablebuttonLayout.addWidget(self.restorepeaklistButton)
        tablebuttonLayout.addWidget(self.savepeaksButton)
        tableLayout.addLayout(tablebuttonLayout)
        self.compoundtab3.setLayout(tableLayout)
        self.compoundTabs.addTab(self.compoundtab3, "Peaklist Table")

        winLayout.addWidget(self.compoundTabs)
        winLayout.addItem(QSpacerItem(0, 20, QSizePolicy.Maximum))
        winLayout.addWidget(self.closeButton)
        winLayout.setAlignment(self.closeButton, Qt.AlignCenter)

    def createConnections(self):
        self.editinfoButton.clicked.connect(self.editInfo)
        self.restoreinfoButton.clicked.connect(self.restoreInfo)
        self.savestructureButton.clicked.connect(self.saveStructure)

        self.showignoredregionsCheckBox.stateChanged.connect(self.handleIgnored)
        self.showignoredpeaksCheckBox.stateChanged.connect(self.handleIgnoredPeaks)
        self.resetviewButton.clicked.connect(self.resetSpectra)
        self.savespectrumButton.clicked.connect(self.saveSpectra)

        self.addButton.clicked.connect(self.addPeak)
        self.removeButton.clicked.connect(self.removePeak)
        self.editButton.clicked.connect(self.editPeak)
        self.restorepeaklistButton.clicked.connect(self.resetPeakList)
        self.savepeaksButton.clicked.connect(self.savePeakList)

        self.closeButton.clicked.connect(self.closeEvent)

    def editInfo(self):
        editinfo_win = InfoWindow(self.params, self.compound)
        if editinfo_win.exec_():
            self.modified = True
            self.updateInfo()

    def restoreInfo(self):
        self.compound.restoreOriginalDescriptors()
        self.modified = True
        self.updateInfo()

    def saveStructure(self):
        filename = "%s.png" % self.compound.id
        filepath = os.path.join(self.params.work_dir, filename)
        filestype = "static (*.png *.jpg *.svg)"
        fileObj = QFileDialog.getSaveFileName(self, "Save Structure Image", directory=filepath, filter=filestype)
        if fileObj[0]:
            self.compound.structure_image.save(fileObj[0])

    def handleIgnored(self):
        if self.showignoredregionsCheckBox.isChecked():
            self.show_ignored = True
            self.drawData()
        else:
            self.show_ignored = False
            self.drawData()

    def handleIgnoredPeaks(self):
        if self.showignoredpeaksCheckBox.isChecked():
            self.show_ignored_peaks = True
            self.drawData()
        else:
            self.show_ignored_peaks = False
            self.drawData()

    def resetSpectra(self):
        self.mpl_toolbar.home()
        self.drawData()

    def saveSpectra(self):
        filename = "%s.png" % self.compound.id
        filepath = os.path.join(self.params.work_dir, filename)
        filestype = "static (*.png *.jpg *.svg)"
        fileObj = QFileDialog.getSaveFileName(self, caption="Save Simulated Compound Spectrum", directory=filepath,
                                              filter=filestype)
        if fileObj[0]:
            self.fig.set_size_inches(12, 8)
            plt.savefig(fileObj[0], dpi=200)

    def addPeak(self):
        addpeak_win = PeakWindow(self.params, self.compound)
        if addpeak_win.exec_():
            self.compound.addPeak(tuple(addpeak_win.table_values))
            self.setTable()
            self.modified = True
            self.drawData()

    def editPeak(self):
        selected = self.peakTable.currentRow()
        # status = self.peakTable.item(selected, 0).text()
        chemshift = float(self.peakTable.item(selected, 1).text())
        intensity = float(self.peakTable.item(selected, 2).text())
        width = self.peakTable.item(selected, 3).text()
        if width != 'Default':
            curr_peak = (chemshift, intensity, float(width))
        else:
            curr_peak = (chemshift, intensity)
        editpeak_win = PeakWindow(self.params, self.compound, curr_peak)
        if editpeak_win.exec_():
            self.compound.editPeak(tuple(editpeak_win.table_values))
            self.setTable()
            self.modified = True
            self.drawData()

    def removePeak(self):
        try:
            selected = self.peakTable.currentRow()
            # status = self.peakTable.item(selected, 0).text()
            chemshift = float(self.peakTable.item(selected, 1).text())
            intensity = float(self.peakTable.item(selected, 2).text())
            width = self.peakTable.item(selected, 3).text()
            peak_list = self.compound.mix_peaklist + self.compound.ignored_peaklist
            if width != 'Default':
                curr_peak = (chemshift, intensity, float(width))
            else:
                curr_peak = (chemshift, intensity)
            min_diff = 9999999
            min_i = 9999999
            for i, peak in enumerate(peak_list):
                diff = abs(float(peak[1]) - float(curr_peak[1]))
                if diff < min_diff:
                    min_diff = diff
                    min_i = i
            matched_peak = peak_list[min_i]
            self.compound.removePeak(matched_peak)
            self.setTable()
            self.modified = True
            self.drawData()
        except Exception as e:
            # print(e)
            pass

    def resetPeakList(self):
        self.compound.resetPeakList()
        self.setTable()
        self.modified = True
        self.drawData()

    def savePeakList(self):
        filename = "%s_custom.csv" % self.compound.id
        filepath = os.path.join(self.params.peaklist_dir, filename)
        filestype = "static (*.csv)"
        fileObj = QFileDialog.getSaveFileName(self, caption="Save Custom Peak List", directory=filepath,
                                              filter=filestype)
        if fileObj[0]:
            filename = os.path.basename(fileObj[0])
            peak_list = self.compound.mix_peaklist + self.compound.ignored_peaklist
            with open(fileObj[0], 'w') as peaks_csv:
                writer = csv.writer(peaks_csv)
                header = ['ChemShift', 'Intensity', 'Width']
                writer.writerow(header)
                writer.writerows(peak_list)
            for i, row in enumerate(self.library.library_csv):
                if row[1] == self.compound.id:
                    self.library.library_csv[i][5] = filename
                    self.library.library_csv[i][6] = 'USER'

    def lorentzian(self, mu, hwhm, intensity):
        def f(x):
            numerator = hwhm ** 2
            denominator = pow((x - mu), 2) + (hwhm ** 2)
            total = intensity * (numerator / denominator)
            return(total)
        return(f)

    def drawPeakData(self, peaks, color="red", alpha=1.0):
        for peak in peaks:
            if len(peak) == 3:
                width = peak[2] * 3
                hwhm = peak[2] * self.params.peak_display_width
            else:
                width = self.params.peak_range * 3
                hwhm = self.params.peak_range * self.params.peak_display_width
            mean = peak[0]
            intensity = peak[1]
            shifts = (np.arange(mean-width, mean+width, 0.001))
            f = self.lorentzian(mean, hwhm, intensity)
            y = ([f(x) for x in shifts])
            self.ax.plot(shifts, y, color=color, linewidth=1, alpha=alpha)

    def drawIgnoredRegions(self, ignored_list):
        updated_ignored = list(set(ignored_list))
        for ignored in updated_ignored:
            ignored_width = abs(ignored[1] - ignored[0])
            ignored_center = (ignored[1] + ignored[0]) / 2
            self.ax.bar(ignored_center, 100, width=ignored_width, color='gray', align='center', edgecolor='gray',
                        linewidth=1, alpha=0.6, picker=True)
            self.ax.bar(ignored_center, -100, width=ignored_width, color='gray', align='center', edgecolor='gray',
                        linewidth=1, alpha=0.6, picker=True)


    def drawData(self):
        self.fig.clear()
        self.ax = self.fig.add_subplot(111, projection="My_Axes")
        ignored_regions = []
        pos_peaks = self.compound.mix_peaklist
        ignored_peaks = self.compound.ignored_peaklist
        ignored_regions += list(self.compound.ignored_regions.values())
        self.drawPeakData(pos_peaks)
        if self.show_ignored_peaks:
            self.drawPeakData(ignored_peaks, color='gray', alpha=0.8)
        if self.show_ignored:
            self.drawIgnoredRegions(ignored_regions)
        self.ax.xaxis.set_minor_locator(matplotlib.ticker.AutoMinorLocator())
        self.ax.spines['bottom'].set_position('zero')
        self.ax.get_xaxis().tick_bottom()
        self.ax.get_yaxis().tick_left()
        self.ax.set_xlim(self.params.shift_range[self.params.nuclei])
        self.ax.set_ylim([0, 1])
        self.ax.set_xlabel('Chemical Shift (ppm)', fontweight='bold')
        self.ax.set_ylabel('Intensity (Normalized)', fontweight='bold')
        self.fig.tight_layout()
        self.canvas.draw()

    def clearTable(self):
        """Deletes all rows in the table."""
        while self.peakTable.rowCount() > 0:
            self.peakTable.removeRow(0)

    def setTable(self):
        self.peakTable.setSortingEnabled(False)
        self.clearTable()
        tablesize = len(self.compound.mix_peaklist) + len(self.compound.ignored_peaklist)
        self.peakTable.setRowCount(tablesize)
        for row, peak in enumerate(self.compound.mix_peaklist):
            self.peakTable.setRowHeight(row, 50)
            active = QTableWidgetItem("ACTIVE")
            active.setTextAlignment(Qt.AlignCenter)
            self.peakTable.setItem(row, 0, active)
            chemshift = QTableWidgetItem()
            chemshift.setTextAlignment(Qt.AlignCenter)
            chemshift.setData(Qt.DisplayRole, "%0.3f" % peak[0])
            self.peakTable.setItem(row, 1, chemshift)
            intensity = QTableWidgetItem()
            intensity.setTextAlignment(Qt.AlignCenter)
            intensity.setData(Qt.DisplayRole, "%0.3f" % peak[1])
            self.peakTable.setItem(row, 2, intensity)
            width = QTableWidgetItem()
            width.setTextAlignment(Qt.AlignCenter)
            if len(peak) == 3:
                width.setData(Qt.DisplayRole, "%0.3f" % peak[2])
            else:
                width.setText('Default')
            self.peakTable.setItem(row, 3, width)
        if len(self.compound.mix_peaklist) > 0:
            next_row = len(self.compound.mix_peaklist)
        else:
            next_row = 0
        for row, peak in enumerate(self.compound.ignored_peaklist, start=next_row):
            self.peakTable.setRowHeight(row, 40)
            active = QTableWidgetItem("IGNORED")
            active.setTextAlignment(Qt.AlignCenter)
            self.peakTable.setItem(row, 0, active)
            chemshift = QTableWidgetItem()
            chemshift.setTextAlignment(Qt.AlignCenter)
            chemshift.setData(Qt.DisplayRole, "%0.3f" % peak[0])
            self.peakTable.setItem(row, 1, chemshift)
            intensity = QTableWidgetItem()
            intensity.setTextAlignment(Qt.AlignCenter)
            intensity.setData(Qt.DisplayRole, "%0.3f" % peak[1])
            self.peakTable.setItem(row, 2, intensity)
            width = QTableWidgetItem()
            width.setTextAlignment(Qt.AlignCenter)
            if len(peak) == 3:
                width.setData(Qt.DisplayRole, "%0.3f" % peak[2])
            else:
                width.setText('Default')
            self.peakTable.setItem(row, 3, width)
        if len(self.compound.mix_peaklist)+len(self.compound.ignored_peaklist) > 0:
            next_row = len(self.compound.mix_peaklist)+len(self.compound.ignored_peaklist)
        else:
            next_row = 0
        for row, peak in enumerate(self.compound.removed_peaklist, start=next_row):
            self.peakTable.setRowHeight(row, 40)
            active = QTableWidgetItem("REMOVED")
            active.setTextAlignment(Qt.AlignCenter)
            self.peakTable.setItem(row, 0, active)
            chemshift = QTableWidgetItem()
            chemshift.setTextAlignment(Qt.AlignCenter)
            chemshift.setData(Qt.DisplayRole, float("%0.3f" % peak[0]))
            self.peakTable.setItem(row, 1, chemshift)
            intensity = QTableWidgetItem()
            intensity.setTextAlignment(Qt.AlignCenter)
            intensity.setData(Qt.DisplayRole, float("%0.3f" % peak[1]))
            self.peakTable.setItem(row, 2, intensity)
            if len(peak) == 3:
                width = QTableWidgetItem()
                width.setTextAlignment(Qt.AlignCenter)
                width.setData(Qt.DisplayRole, float("%0.3f" % peak[2]))
                self.peakTable.setItem(row, 3, width)
        self.peakTable.setSortingEnabled(True)
        self.peakTable.selectRow(0)

    def updateInfo(self):
        self.nameLabel.setText("<b>Name:</b> %s" % self.compound.name)
        self.groupLabel.setText("<b>Group:</b> %s" % self.compound.group)
        self.pubchemLabel.setText("<b>PubChem CID:</b> <a href='https://pubchem.ncbi.nlm.nih.gov/compound/%s'>%s</a>"
                                   % (self.compound.pubchem_id, self.compound.pubchem_id))
        self.pubchemLabel.setTextInteractionFlags(Qt.LinksAccessibleByMouse)
        self.pubchemLabel.setOpenExternalLinks(True)
        self.keggLabel.setText("<b>KEGG ID:</b> <a href='http://www.genome.jp/dbget-bin/www_bget?cpd:%s'>%s</a>"
                                % (self.compound.kegg_id, self.compound.kegg_id))
        self.keggLabel.setTextInteractionFlags(Qt.LinksAccessibleByMouse)
        self.keggLabel.setOpenExternalLinks(True)

        if self.compound.smiles:
            self.smilesLabel.setText("<b>SMILES:</b> %s" % self.compound.smiles)
            try:
                self.compound.set2DStructure()
                molformula = ""
                for count, i in enumerate(self.compound.molformula):
                    try:
                        if count > 0:
                            if self.compound.molformula[count-1] == "-" or self.compound.molformula[count-1] == "+":
                                j = "<sup>%d</sup>" % int(i)
                            else:
                                j = "<sub>%d</sub>" % int(i)
                        else:
                            j = i
                    except:
                        if i == "-" or i == "+":
                            j = "<sup>%s</sup>" % i
                        else:
                            j = i
                    molformula += j
                self.molformulaLabel.setText("<b>Mol. Formula:</b> %s" % molformula)
                self.molwtLabel.setText("<b>Mol. Weight:</b> %0.3f" % self.compound.molwt)
                if self.compound.structure_image:
                    self.pixmap = QPixmap.fromImage(self.compound.structure_qt)
                    self.structure.setText("")
                    self.structure.setPixmap(self.pixmap)
                    self.structure.setAlignment(Qt.AlignCenter)
                else:
                    self.structure.setText("No Structure Available")
                    self.structure.setAlignment(Qt.AlignCenter)
            except:
                self.molformulaLabel.setText("<b>Mol. Formula:</b> Unknown")
                self.molwtLabel.setText("<b>Mol. Weight:</b> Unknown")
        else:
            self.smilesLabel.setText("<b>SMILES:</b> Unknown")
            self.molformulaLabel.setText("<b>Mol. Formula:</b> Unknown")
            self.molwtLabel.setText("<b>Mol. Weight:</b> Unknown")
            self.structure.setText("No Structure Available")
            self.structure.setAlignment(Qt.AlignCenter)

        for i, row in enumerate(self.library.library_csv):
                if row[1] == self.compound.id:
                    self.library.library_csv[i][2] = self.compound.name
                    self.library.library_csv[i][3] = self.compound.bmrb_id
                    self.library.library_csv[i][4] = self.compound.hmdb_id
                    self.library.library_csv[i][8] = self.compound.pubchem_id
                    self.library.library_csv[i][9] = self.compound.kegg_id
                    self.library.library_csv[i][10] = self.compound.smiles


    def zooming(self, event):
        cur_ylim = self.ax.get_ylim()
        cur_yrange = (cur_ylim[1] - cur_ylim[0])
        if event.button == 'up':
            scale_factor = self.scale
        elif event.button == 'down':
            scale_factor = 1/self.scale
        else:
            scale_factor = 1

        self.ax.set_ylim([0, (cur_yrange*scale_factor)])
        self.canvas.draw()

    def acceptChanges(self):
        pass

    def closeEvent(self, event=False):
        self.fig.clear()
        QDialog.accept(self)
Beispiel #56
0
class univariaterowDlg(QtWidgets.QDialog, Ui_univariaterowDialog):
    def __init__(self, parent=None):
        super(univariaterowDlg, self).__init__(parent)
        self.setupUi(self)
        self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.CustomizeWindowHint
                            | QtCore.Qt.WindowTitleHint
                            | QtCore.Qt.WindowCloseButtonHint
                            | QtCore.Qt.WindowMaximizeButtonHint)
        self.XcomboBox.addItems(DS.Lr[DS.Ir])
        self.XcomboBox.setCurrentIndex(0)
        self.histogramradioButton.setChecked(True)
        self.spinBox.setDisabled(True)
        self.TcheckBox.setChecked(True)
        self.XGcheckBox.setChecked(False)
        self.YGcheckBox.setChecked(False)
        self.XMcheckBox.setChecked(True)
        self.YMcheckBox.setChecked(True)
        self.XcheckBox.setChecked(True)
        self.YcheckBox.setChecked(True)
        self.ApplyButton.clicked.connect(self.redraw)
        self.ResetButton.clicked.connect(self.reset)
        self.BootmeanradioButton.clicked.connect(self.deactivate)
        self.BootsdradioButton.clicked.connect(self.deactivate)
        self.BoxCoxradioButton.clicked.connect(self.deactivate1)
        self.histogramradioButton.clicked.connect(self.activate)
        self.NormalityradioButton.clicked.connect(self.activate)
        self.PPCCradioButton.clicked.connect(self.activate)
        self.BoxradioButton.clicked.connect(self.activate)
        fig = Figure()
        ax = fig.add_subplot(111)
        ax.plot(np.array(0))
        ax.set_xlim([0, 1])
        ax.set_ylim([0, 1])
        self.addmpl(fig)

    def activate(self):
        self.spinBox.setDisabled(True)
        self.TcheckBox.setDisabled(False)
        self.XcheckBox.setDisabled(False)
        self.YcheckBox.setDisabled(False)
        self.XMcheckBox.setDisabled(False)
        self.YMcheckBox.setDisabled(False)
        self.XGcheckBox.setDisabled(False)
        self.YGcheckBox.setDisabled(False)

    def deactivate(self):
        self.TcheckBox.setDisabled(True)
        self.XcheckBox.setDisabled(True)
        self.YcheckBox.setDisabled(True)
        self.XMcheckBox.setDisabled(True)
        self.YMcheckBox.setDisabled(True)
        self.XGcheckBox.setDisabled(True)
        self.YGcheckBox.setDisabled(True)
        self.spinBox.setDisabled(False)

    def deactivate1(self):
        self.TcheckBox.setDisabled(True)
        self.XcheckBox.setDisabled(True)
        self.YcheckBox.setDisabled(True)
        self.XMcheckBox.setDisabled(True)
        self.YMcheckBox.setDisabled(True)
        self.XGcheckBox.setDisabled(True)
        self.YGcheckBox.setDisabled(True)

    def redraw(self):
        def bootstrap(data, num_samples, statistic, alpha):
            n = len(data)
            idx = random.randint(0, n, (num_samples, n))
            samples = data[idx]
            stat = np.sort(statistic(samples, 1))
            return (stat[int((alpha / 2.0) * num_samples)], stat[int(
                (1 - alpha / 2.0) * num_samples)], samples)

        if self.XcomboBox.currentText(
        ) == 'all' and not self.trendradioButton.isChecked():
            QtWidgets.QMessageBox.critical(
                self, 'Error',
                "All rows can be plotted \n only using : Trend !",
                QtWidgets.QMessageBox.Ok)
            return ()
        color = 'blue'
        data = DS.Raw.iloc[DS.Ir, DS.Ic]
        data = pd.DataFrame(data.T)
        data.columns = np.array(data.columns, dtype='<U25')
        data = data.assign(Lc=DS.Lc[DS.Ic])
        data = data.assign(Cc=DS.Cc[DS.Ic])
        data = data[[self.XcomboBox.currentText(), 'Lc', 'Cc']]
        if data.shape[1] != 3:
            QtWidgets.QMessageBox.critical(self,'Error',"More rows have the same name",\
                                           QtWidgets.QMessageBox.Ok)
            return ()
        Nnan = data.isnull().sum().sum() > 0
        data = data.dropna()
        Lc = data['Lc'].values
        Cc = data['Cc'].values
        data = data.drop('Lc', axis=1)
        data = data.drop('Cc', axis=1)
        Y = data.values.ravel()
        if Y.dtype == 'float' and Y.dtype == 'int':
            QtWidgets.QMessageBox.critical(self,'Error',"Some values are not numbers!",\
                                           QtWidgets.QMessageBox.Ok)
            return ()
        if self.CcheckBox.isChecked():
            color = Cc[self.XcomboBox.currentIndex()]
        fig = Figure()
        ax = fig.add_subplot(111)
        if (self.BoxradioButton.isChecked()):
            medianprops = dict(marker='D',
                               markeredgecolor='black',
                               markerfacecolor=color)
            ax.boxplot(Y, vert=1, medianprops=medianprops)
            if self.YcheckBox.isChecked():
                if self.YlineEdit.text():
                    ax.set_ylabel(self.YlineEdit.text())
            if self.XcheckBox.isChecked():
                if self.XlineEdit.text():
                    ax.set_xlabel(self.YlineEdit.text())
            if Nnan:
                ax.annotate('NaN present',
                            xy=(0.80, 0.95),
                            xycoords='axes fraction')
        elif (self.NormalityradioButton.isChecked()):
            stats.probplot(Y, plot=ax)
            if self.XcheckBox.isChecked():
                if self.XlineEdit.text():
                    ax.set_xlabel('Normal N(0,1) Statistic Medians')
            if self.YcheckBox.isChecked():
                if self.YlineEdit.text():
                    ax.set_ylabel('Ordered Responce')
            if Nnan:
                ax.annotate('NaN present',
                            xy=(0.05, 0.95),
                            xycoords='axes fraction')
        elif (self.PPCCradioButton.isChecked()):
            stats.ppcc_plot(Y, -6, 6, plot=ax)
            if self.XcheckBox.isChecked():
                if self.XlineEdit.text():
                    ax.set_xlabel('Shape Values')
            if self.YcheckBox.isChecked():
                if self.YlineEdit.text():
                    ax.set_ylabel('Prob.Plot.Corr.Coef.')
            if Nnan:
                ax.annotate('NaN present',
                            xy=(0.05, 0.95),
                            xycoords='axes fraction')
        elif (self.BoxCoxradioButton.isChecked()):
            fig = Figure()
            if not (Y > 0).all():
                QtWidgets.QMessageBox.critical(self,'Error',"Data must be strictly positive!",\
                                               QtWidgets.QMessageBox.Ok)
                return ()
            bins = np.linspace(Y.min(), Y.max(), 21)
            ax1 = fig.add_subplot(2,
                                  2,
                                  1,
                                  title="Original " +
                                  self.XcomboBox.currentText())
            ax1.hist(Y,
                     bins=bins,
                     histtype='bar',
                     color=color,
                     alpha=0.5,
                     orientation="vertical",
                     label="x")
            if Nnan:
                ax1.annotate('NaN present',
                             xy=(0.80, 0.95),
                             xycoords='figure fraction')
            trans_y, lambda_ = stats.boxcox(Y)
            ax2 = fig.add_subplot(2,
                                  2,
                                  2,
                                  title='Transformed Data (lambda=' +
                                  str(round(lambda_, 2)) + ')')
            bins = np.linspace(np.amin(trans_y), np.amax(trans_y), 21)
            ax2.hist(trans_y,
                     bins=bins,
                     histtype='bar',
                     color=color,
                     alpha=0.5,
                     orientation="vertical",
                     label="x Transformed")
            ax3 = fig.add_subplot(2,
                                  2,
                                  3,
                                  title="Original " +
                                  self.XcomboBox.currentText())
            stats.probplot(Y, dist='norm', plot=ax3)
            ax4 = fig.add_subplot(2, 2, 4)
            stats.probplot(trans_y, dist='norm', plot=ax4)
            ax4.set_title('Transformed Data (lambda=' +
                          str(round(lambda_, 2)) + ')')
        elif (self.logisticradioButton.isChecked()):
            stats.probplot(Y, dist=stats.logistic, plot=ax)
            ax.set_xlabel('Quantiles')
            ax.set_ylabel("Ordered " + self.XcomboBox.currentText())
            ax.set_title('Logistic', fontsize=12)
            if Nnan:
                ax.annotate('NaN present',
                            xy=(0.80, 0.95),
                            xycoords='axes fraction')
        elif (self.laplaceradioButton.isChecked()):
            stats.probplot(Y, dist=stats.laplace, plot=ax)
            ax.set_xlabel('Quantiles')
            ax.set_ylabel('Ordered ' + self.XcomboBox.currentText())
            ax.set_title('Laplace', fontsize=12)
            if Nnan:
                ax.annotate('NaN present',
                            xy=(0.80, 0.95),
                            xycoords='axes fraction')
        elif (self.logammaradioButton.isChecked()):
            shape = float(self.logammadoubleSpinBox.value())
            stats.probplot(Y, dist=stats.loggamma, sparams=shape, plot=ax)
            ax.set_xlabel('Quantiles')
            ax.set_ylabel("Ordered " + self.XcomboBox.currentText())
            ax.set_title('Log Gamma with shape ' + str(shape), fontsize=12)
            if Nnan:
                ax.annotate('NaN present',
                            xy=(0.80, 0.95),
                            xycoords='axes fraction')
        elif (self.lognormalradioButton.isChecked()):
            shape = float(self.lognormdoubleSpinBox.value()) / 10.
            stats.probplot(Y, dist=stats.lognorm, sparams=(shape), plot=ax)
            ax.set_xlabel('Quantiles')
            ax.set_ylabel("Ordered " + self.XcomboBox.currentText())
            ax.set_title('Log norm with shape ' + str(shape), fontsize=12)
            if Nnan:
                ax.annotate('NaN present',
                            xy=(0.80, 0.95),
                            xycoords='axes fraction')
        elif (self.BootmeanradioButton.isChecked()):
            fig = Figure()
            ax1 = fig.add_subplot(1,
                                  2,
                                  1,
                                  title="Historgram of " +
                                  self.XcomboBox.currentText())
            low, high, samples = bootstrap(Y, self.spinBox.value(), np.mean,
                                           0.05)
            points = np.mean(samples, 1)
            ax1.hist(points, 50, histtype='step')
            if Nnan:
                ax1.annotate('NaN present',
                             xy=(0.80, 0.95),
                             xycoords='figure fraction')
            ax2 = fig.add_subplot(1, 2, 2, title='Bootstrap 95% CI for mean')
            ax2.scatter(0.1 * (random.random(len(points)) - 0.5), points)
            ax2.plot([0.19, 0.21], [low, low], 'r', linewidth=2)
            ax2.plot([0.19, 0.21], [high, high], 'r', linewidth=2)
            ax2.plot([0.2, 0.2], [low, high], 'r', linewidth=2)
            ax2.set_xlim([-0.2, 0.3])
        elif (self.BootsdradioButton.isChecked()):
            fig = Figure()
            ax1 = fig.add_subplot(1,
                                  2,
                                  1,
                                  title="Historgram of " +
                                  self.XcomboBox.currentText())
            low, high, samples = bootstrap(Y, self.spinBox.value(), np.std,
                                           0.05)
            points = np.std(samples, 1)
            ax1.hist(points, 50, histtype='step')
            if Nnan:
                ax1.annotate('NaN present',
                             xy=(0.80, 0.95),
                             xycoords='figure fraction')
            ax2 = fig.add_subplot(
                1, 2, 2, title='Bootstrap 95% CI for standard deviation')
            ax2.scatter(0.1 * (random.random(len(points)) - 0.5), points)
            ax2.plot([0.19, 0.21], [low, low], 'r', linewidth=2)
            ax2.plot([0.19, 0.21], [high, high], 'r', linewidth=2)
            ax2.plot([0.2, 0.2], [low, high], 'r', linewidth=2)
            ax2.set_xlim([-0.2, 0.3])
        elif (self.histogramradioButton.isChecked()):
            iqr = np.percentile(Y, [75, 25])
            iqr = iqr[0] - iqr[1]
            n = Y.shape[0]
            dy = abs(float(Y.max()) - float(Y.min()))
            nbins = np.floor(dy / (2 * iqr) * n**(1 / 3)) + 1
            nbins = 2 * nbins
            bins = np.linspace(Y.min(), Y.max(), nbins)
            ax.hist(Y,
                    bins=bins,
                    histtype='bar',
                    color=color,
                    alpha=0.5,
                    orientation='vertical',
                    label="X")
            if Nnan:
                ax.annotate('NaN present',
                            xy=(0.80, 0.95),
                            xycoords='axes fraction')
        elif (self.trendradioButton.isChecked()):
            nr = len(Y)
            ind = np.array(range(1, nr + 1))
            ax.scatter(ind, Y, marker='o', color=color)
            if self.LcheckBox.isChecked():
                ax.plot(ind, Y, color=color)
            if (nr > 30):
                itick = np.linspace(0, nr - 1, 20).astype(int)
                ltick = Lc[itick]
            else:
                itick = ind
                ltick = Lc
            ax.set_xlim([0, nr + 2])
            ax.set_xticks(itick)
            ax.set_xticklabels(ltick, rotation='vertical')
            ax.set_ylabel(self.XcomboBox.currentText())
            if Nnan:
                ax.annotate('NaN present',
                            xy=(0.80, 0.95),
                            xycoords='axes fraction')
        if self.TcheckBox.isChecked():
            if self.TlineEdit.text():
                ax.set_title(self.TlineEdit.text())
        else:
            ax.set_title('')
        if self.XcheckBox.isChecked():
            if self.XlineEdit.text():
                ax.set_xlabel(self.XlineEdit.text())
        else:
            ax.set_xlabel('')
        if self.YcheckBox.isChecked():
            ax.set_ylabel(self.YlineEdit.text())
        else:
            ax.set_ylabel('')
        if self.XGcheckBox.isChecked():
            ax.xaxis.grid(True)
        else:
            ax.xaxis.grid(False)
        if self.YGcheckBox.isChecked():
            ax.yaxis.grid(True)
        else:
            ax.yaxis.grid(False)
        if not self.XMcheckBox.isChecked():
            ax.tick_params(axis='x',
                           which='both',
                           bottom='off',
                           top='off',
                           labelbottom='off')
        if not self.YMcheckBox.isChecked():
            ax.tick_params(axis='y',
                           which='both',
                           left='off',
                           right='off',
                           labelleft='off')
        self.rmmpl()
        self.addmpl(fig)

    def reset(self):
        self.XcomboBox.setCurrentIndex(0)
        self.XGcheckBox.setChecked(False)
        self.YGcheckBox.setChecked(False)
        self.XMcheckBox.setChecked(False)
        self.YMcheckBox.setChecked(True)
        self.XcheckBox.setChecked(True)
        self.YcheckBox.setChecked(True)
        self.XlineEdit.setText('')
        self.YlineEdit.setText('')
        self.TlineEdit.setText('')
        self.update()

    def addmpl(self, fig):
        self.canvas = FigureCanvas(fig)
        self.mplvl.addWidget(self.canvas)
        self.canvas.draw()
        self.toolbar = NavigationToolbar(self.canvas,
                                         self.mplwindow,
                                         coordinates=True)
        self.mplvl.addWidget(self.toolbar)

    def rmmpl(self, ):
        self.mplvl.removeWidget(self.canvas)
        self.canvas.close()
        self.mplvl.removeWidget(self.toolbar)
        self.toolbar.close()
Beispiel #57
0
class FigureFrame(qw.QFrame):

    def __init__(self, parent=None):
        qw.QFrame.__init__(self, parent)

        # bgrgb = self.palette().color(qw.QPalette.Window).getRgb()[:3]
        fgcolor = plot.tango_colors['aluminium5']
        dpi = 0.5*(self.logicalDpiX() + self.logicalDpiY())

        font = qg.QFont()
        font.setBold(True)
        fontsize = font.pointSize()

        import matplotlib
        matplotlib.rcdefaults()
        if use_pyqt5:
            try:
                matplotlib.rcParams['backend'] = 'Qt5Agg'
            except ValueError:
                matplotlib.rcParams['backend'] = 'Qt4Agg'
        else:
            matplotlib.rcParams['backend'] = 'Qt4Agg'

        matplotlib.rc('xtick', direction='out', labelsize=fontsize)
        matplotlib.rc('ytick', direction='out', labelsize=fontsize)
        matplotlib.rc('xtick.major', size=8)
        matplotlib.rc('xtick.minor', size=4)
        matplotlib.rc('ytick.major', size=8)
        matplotlib.rc('ytick.minor', size=4)
        # matplotlib.rc(
        #     'figure', facecolor=tohex(bgrgb), edgecolor=tohex(fgcolor))
        matplotlib.rc('figure', facecolor='white', edgecolor=tohex(fgcolor))
        matplotlib.rc(
            'font', family='sans-serif', weight='bold', size=fontsize,
            **{'sans-serif': [font.family()]})
        matplotlib.rc('text', color=tohex(fgcolor))
        matplotlib.rc('xtick', color=tohex(fgcolor))
        matplotlib.rc('ytick', color=tohex(fgcolor))
        matplotlib.rc('figure.subplot', bottom=0.15)

        matplotlib.rc('axes', linewidth=0.5, unicode_minus=False)
        matplotlib.rc(
            'axes',
            facecolor='white',
            edgecolor=tohex(fgcolor),
            labelcolor=tohex(fgcolor))

        try:
            from cycler import cycler
            matplotlib.rc(
                'axes', prop_cycle=cycler(
                    'color', [to01(x) for x in plot.graph_colors]))

        except (ImportError, KeyError):
            try:
                matplotlib.rc('axes', color_cycle=[
                    to01(x) for x in plot.graph_colors])

            except KeyError:
                pass

        try:
            matplotlib.rc('axes', labelsize=fontsize)
        except KeyError:
            pass

        try:
            matplotlib.rc('axes', labelweight='bold')
        except KeyError:
            pass

        from matplotlib.figure import Figure

        if use_pyqt5:
            from matplotlib.backends.backend_qt5agg import \
                NavigationToolbar2QT as NavigationToolbar

            from matplotlib.backends.backend_qt5agg \
                import FigureCanvasQTAgg as FigureCanvas
        else:
            try:
                from matplotlib.backends.backend_qt4agg import \
                    NavigationToolbar2QTAgg as NavigationToolbar
            except ImportError:
                from matplotlib.backends.backend_qt4agg import \
                    NavigationToolbar2QT as NavigationToolbar

            from matplotlib.backends.backend_qt4agg \
                import FigureCanvasQTAgg as FigureCanvas

        layout = qw.QGridLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)

        self.setLayout(layout)
        self.figure = Figure(dpi=dpi)
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setParent(self)
        self.toolbar = NavigationToolbar(self.canvas, self)
        layout.addWidget(self.toolbar, 0, 0)
        layout.addWidget(self.canvas, 1, 0)
        self.closed = False

    def gca(self):
        axes = self.figure.gca()
        beautify_axes(axes)
        return axes

    def gcf(self):
        return self.figure

    def draw(self):
        '''Draw with AGG, then queue for Qt update.'''
        self.canvas.draw()

    def closeEvent(self, ev):
        self.closed = True
Beispiel #58
0
class BackTestResult(QDialog):
    def __init__(self, ACid):
        super().__init__()
        f = FETCH()
        self.risk = f.fetch_risk(AC_id=ACid)
        self.account = f.fetch_account(AC_id=ACid)
        self.initUI()

    def initUI(self):
        self.resize(1000, 700)
        self.setWindowTitle("QUANT XH 金融终端")
        self.setWindowIcon(QIcon("static/icon.png"))
        self.figure = plt.figure(facecolor='#FFFFFF')
        self.canvas = FigureCanvas(self.figure)
        self.Draw()

        self.tb = QTextBrowser()
        self.tb.setFixedSize(300,500)
        self.tb.setFont(QFont("仿宋", 10))
        for line in self.account["history"]:
            s = str(line[0])
            if line[3] >= 0:
                s += " 买入"
            else:
                s += " 卖出"
            s += line[1] + "共" + str(abs(line[3])) + "股,单股价格是" + str(line[2]) + "\n"
            self.tb.append(s)

        self.hbox = QHBoxLayout()
        self.hbox.addWidget(self.canvas)
        self.hbox.addWidget(self.tb)

        self.grid = QGridLayout()

        label = QLabel()
        label.setText("回测收益:"+str(self.risk["profit"]))
        label.setFont(QFont("仿宋", 12))
        self.grid.addWidget(label,0,0)
        label = QLabel()
        label.setText("年化回测收益:" + str(self.risk["annualize_return"]))
        label.setFont(QFont("仿宋", 12))
        self.grid.addWidget(label, 0, 1)
        label = QLabel()
        label.setText("基准收益:" + str(self.risk["bm_profit"]))
        label.setFont(QFont("仿宋", 12))
        self.grid.addWidget(label, 0, 2)
        label = QLabel()
        label.setText("年化基准收益:" + str(self.risk["bm_annualizereturn"]))
        label.setFont(QFont("仿宋", 12))
        self.grid.addWidget(label, 0, 3)

        label = QLabel()
        label.setText("Alpha:" + str(self.risk["alpha"]))
        label.setFont(QFont("仿宋", 12))
        self.grid.addWidget(label, 1, 0)
        label = QLabel()
        label.setText("Beta:" + str(self.risk["beta"]))
        label.setFont(QFont("仿宋", 12))
        self.grid.addWidget(label, 1, 1)
        label = QLabel()
        label.setText("夏普率:" + str(self.risk["sharpe"]))
        label.setFont(QFont("仿宋", 12))
        self.grid.addWidget(label, 1, 2)
        label = QLabel()
        label.setText("信息比率:" + str(self.risk["ir"]))
        label.setFont(QFont("仿宋", 12))
        self.grid.addWidget(label, 1, 3)

        label = QLabel()
        label.setText("波动性:" + str(self.risk["volatility"]))
        label.setFont(QFont("仿宋", 12))
        self.grid.addWidget(label, 2, 0)
        label = QLabel()
        label.setText("最大回撤:" + str(self.risk["max_dropback"]))
        label.setFont(QFont("仿宋", 12))
        self.grid.addWidget(label, 2, 1)

        self.layout = QVBoxLayout()
        self.layout.addLayout(self.hbox)
        self.layout.addLayout(self.grid)
        self.setLayout(self.layout)

    def Draw(self):

        xs = [datetime.strptime(d, '%Y-%m-%d').date() for d in self.risk["totaltimeindex"]]
        plt.plot(xs,self.risk["assets"], color = 'red', linewidth = 2)
        plt.plot(xs,self.risk["benchmark_assets"], color="blue",linewidth=2)

        self.canvas.draw()
Beispiel #59
0
class FitMainGui(QtWidgets.QMainWindow):
    # define main GUI window of the simulator
    def __init__(self, parent=None):       # initialize GUI
        super().__init__()

        # initialize fit parameter & fit status instance
        self.fit_par = FitParameter(1)
        self.fit_stat = FitStatus()
        # initialize input validity tracker
        self.fit_stat.input_valid = True
        # get log directory (local directory of the script)
        self.log_dir = os.getcwd()
        # get file directory (read last directory from .cfg file)
        self.current_dir = self.get_file_dir()

        # add aborted and successful file list
        self.list_aborted_file = []
        self.list_success_file = []

        # add menubar
        openAction = QtWidgets.QAction('Open', self)
        openAction.setShortcut('Ctrl+O')
        openAction.setStatusTip('Open Spectra')
        openAction.triggered.connect(self.open_file)
        self.menu = self.menuBar()
        self.menu.setNativeMenuBar(False)
        self.menu.addAction(openAction)

        # add status bar
        self.statusbar = self.statusBar()

        # set GUI layout
        self.set_main_grid()
        self.widget_main = QtWidgets.QWidget()
        self.widget_main.setLayout(self.layout_main)
        self.setCentralWidget(self.widget_main)

        # set program title
        self.setWindowTitle('Fit Spectra!')

        # show program window
        self.show()

    def set_main_grid(self):
        self.layout_main = QtWidgets.QGridLayout()
        self.layout_main.setSpacing(6)

        # add current_file label
        self.label_current_file = QtWidgets.QLabel()
        self.layout_main.addWidget(QtWidgets.QLabel('Current File:'), 0, 0)
        self.layout_main.addWidget(self.label_current_file, 0, 1, 1, 2)

        # add matplotlib canvas
        self.fig = plt.figure()
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setFocus()
        self.mpl_toolbar = NavigationToolbar(self.canvas, self)
        self.click_counter = 0      # initialize click counter
        # connect the canvas to matplotlib standard key press events
        self.canvas.mpl_connect('key_press_event', self.mpl_key_press)
        # connect the canvas to mouse click events
        self.canvas.mpl_connect('button_press_event', self.mpl_click)
        self.layout_main.addWidget(self.mpl_toolbar, 1, 0, 1, 3)
        self.layout_main.addWidget(self.canvas, 2, 0, 1, 3)

        # add fit option layout
        self.layout_setting = QtWidgets.QGridLayout()
        # select lineshape
        self.combo_ftype = QtWidgets.QComboBox()
        self.combo_ftype.addItems(['Gaussian', 'Lorentzian'])
        # select number of derivatives
        self.combo_der = QtWidgets.QComboBox()
        self.combo_der.addItems(['0', '1', '2', '3', '4'])
        self.check_boxcar = QtWidgets.QCheckBox('Boxcar Smooth?')
        self.check_rescale = QtWidgets.QCheckBox('Rescale Intensity?')
        self.edit_boxcar = QtWidgets.QLineEdit('1')
        self.edit_rescale = QtWidgets.QLineEdit('1')
        self.edit_deg = QtWidgets.QLineEdit('0')
        self.edit_num_peak = QtWidgets.QLineEdit('1')
        self.layout_setting.addWidget(QtWidgets.QLabel('Lineshape Function'), 0, 0)
        self.layout_setting.addWidget(self.combo_ftype, 1, 0)
        self.layout_setting.addWidget(QtWidgets.QLabel('Derivative'), 0, 1)
        self.layout_setting.addWidget(self.combo_der, 1, 1)
        self.layout_setting.addWidget(self.check_boxcar, 2, 0)
        self.layout_setting.addWidget(self.edit_boxcar, 2, 1)
        self.layout_setting.addWidget(self.check_rescale, 3, 0)
        self.layout_setting.addWidget(self.edit_rescale, 3, 1)
        self.layout_setting.addWidget(QtWidgets.QLabel('PolyBaseline Degree'), 4, 0)
        self.layout_setting.addWidget(self.edit_deg, 4, 1)
        self.layout_setting.addWidget(QtWidgets.QLabel('Number of Peaks'), 5, 0)
        self.layout_setting.addWidget(self.edit_num_peak, 5, 1)
        self.layout_setting.addWidget(QtWidgets.QLabel('<<< Initial Guess >>>'), 6, 0, 2, 2)
        # connect signals
        # select combo box items
        self.combo_ftype.currentIndexChanged.connect(self.get_ftype)
        self.combo_der.currentIndexChanged.connect(self.get_der)
        # display/hide checked edit box
        self.edit_boxcar.hide()
        self.edit_rescale.hide()
        self.check_boxcar.stateChanged.connect(self.show_boxcar)
        self.check_rescale.stateChanged.connect(self.show_rescale)
        # check input validity
        self.edit_boxcar.textChanged.connect(self.check_int_validity)
        self.edit_rescale.textChanged.connect(self.check_double_validity)
        self.edit_deg.textChanged.connect(self.check_int_validity)
        self.edit_num_peak.textChanged.connect(self.set_par_layout)

        # add fit parameter layout for initial guess
        self.widget_par = QtWidgets.QWidget()
        self.layout_par = QtWidgets.QGridLayout()
        self.edit_par = []
        self.set_par_layout()
        self.widget_par.setLayout(self.layout_par)
        self.scroll_par = QtWidgets.QScrollArea()
        self.scroll_par.setWidget(self.widget_par)
        self.scroll_par.setWidgetResizable(True)
        self.scroll_par.setMaximumHeight(600)
        self.layout_setting.addWidget(self.scroll_par, 8, 0, 1, 2)

        self.layout_main.addLayout(self.layout_setting, 2, 3)

        # add fit & Quit button
        btn_fit = QtWidgets.QPushButton('Fit Spectrum', self)
        btn_quit = QtWidgets.QPushButton('Quit', self)
        btn_quit.setShortcut('Ctrl+Q')
        self.layout_main.addWidget(btn_fit, 0, 3)
        self.layout_main.addWidget(btn_quit, 3, 3)
        btn_fit.clicked.connect(self.fit_routine)
        btn_quit.clicked.connect(self.close)

    def set_par_layout(self):
        text = self.edit_num_peak.text()
        try:
            self.fit_par.peak = abs(int(text))
            green = '#00A352'
            self.edit_num_peak.setStyleSheet('border: 3px solid %s' % green)
        except ValueError:
            red = '#D63333'
            self.edit_num_peak.setStyleSheet('border: 3px solid %s' % red)
            self.fit_par.peak = 0
        # set initial guess layout
        # clear previous parameters
        self.fit_par.par = np.zeros(self.fit_par.peak * self.fit_par.par_per_peak)
        self.edit_par = []          # clear previous widgets
        self.clear_item(self.layout_par)   # clear layout
        self.click_counter = 0      # reset click counter
        # add widgets
        for i in range(self.fit_par.par_per_peak * self.fit_par.peak):
            peak_index = i // self.fit_par.par_per_peak + 1
            par_index = i % self.fit_par.par_per_peak
            self.edit_par.append(QtWidgets.QLineEdit())
            if par_index:   # starting of a new peak
                self.layout_par.addWidget(QtWidgets.QLabel(
                                    '--- Peak {:d} ---'.format(peak_index)),
                                     4*(peak_index-1), 0, 1, 2)
            self.layout_par.addWidget(QtWidgets.QLabel(
                                    self.fit_par.par_name[par_index]), i+peak_index, 0)
            self.layout_par.addWidget(self.edit_par[i], i+peak_index, 1)
            self.edit_par[i].setText('0.5')     # set default value
            self.edit_par[i].textChanged.connect(self.check_double_validity)

    # --------- get all fitting options ---------

    def get_ftype(self, ftype):
        self.fit_par.ftype = ftype
        self.fit_par.par_name = self.fit_par.get_par_name(ftype)
        # refresh parameter layout
        self.set_par_layout()

    def get_der(self, der):
        self.fit_par.der = der

    def get_par(self):
        # if input is valid
        if self.fit_stat.input_valid == 2:
            for i in range(self.fit_par.par_per_peak * self.fit_par.peak):
                self.fit_par.par[i] = float(self.edit_par[i].text())
            self.fit_par.boxwin = abs(int(self.edit_boxcar.text()))
            self.fit_par.rescale = abs(float(self.edit_rescale.text()))
            self.fit_par.deg = abs(int(self.edit_deg.text()))
        else:
            self.fit_stat.stat = 5

    # --------- fit routine ---------

    def fit_routine(self):
        # if data loaded successfully
        if not self.fit_stat.stat:
            data_table, popt, uncertainty, ppoly = self.fit_try()

        # if fit failed, print information
        if self.fit_stat.stat:
            failure = QtWidgets.QMessageBox.information(self, 'Failure',
                      self.fit_stat.print_stat(), QtWidgets.QMessageBox.Retry |
                      QtWidgets.QMessageBox.Abort, QtWidgets.QMessageBox.Retry)
            # choose retry or ignore
            if failure ==  QtWidgets.QMessageBox.Retry:
                pass
            elif failure == QtWidgets.QMessageBox.Abort:
                self.pass_file()
        # if fit successful, ask user for save|retry option
        else:
            success = QtWidgets.QMessageBox.question(self, 'Save?',
                      'Save the fit if it looks good. \n ' +
                      'Otherwise retry a fit or abort this file ',
                      QtWidgets.QMessageBox.Save | QtWidgets.QMessageBox.Retry |
                      QtWidgets.QMessageBox.Abort, QtWidgets.QMessageBox.Save)
            if success == QtWidgets.QMessageBox.Save:
                # save file
                self.save_file(data_table, popt, uncertainty, ppoly)
                # go to next spectrum
                self.next_file()
            elif success == QtWidgets.QMessageBox.Retry:
                pass
            elif success == QtWidgets.QMessageBox.Abort:
                self.pass_file()

    def fit_try(self):
        # get fitting parameters
        self.get_par()

        if not self.fit_stat.stat:
            if self.fit_par.peak:
                # get fit function
                f = self.fit_par.get_function()
                # re-load data with boxcar win and rescale
                xdata, ydata = self.load_data()
                popt, uncertainty, noise, ppoly, self.fit_stat.stat = sflib.fit_spectrum(f,
                xdata, ydata, self.fit_par.par, self.fit_par.deg, self.fit_par.smooth_edge)
            else:    # if no peak, fit baseline
                xdata, ydata = self.load_data()
                popt, uncertainty, noise, ppoly, self.fit_stat.stat = sflib.fit_baseline(xdata, ydata, self.fit_par.deg)

        # if fit successful, plot fit
        if not self.fit_stat.stat and self.fit_par.peak:
            # Make plot for successful fit
            fit = f.get_func()(xdata, *popt)
            baseline = np.polyval(ppoly, xdata - np.median(xdata))
            residual = ydata - fit - baseline
            self.statusbar.showMessage('Noise {:.4f}'.format(noise))
            self.plot_spect(xdata, ydata, fit, baseline)
            # concatenate data table
            data_table = np.column_stack((xdata, ydata, fit, baseline))
            return data_table, popt, uncertainty, ppoly
        elif not self.fit_stat.stat:
            baseline = np.polyval(ppoly, xdata - np.median(xdata))
            residual = ydata - baseline
            fit = np.zeros_like(ydata)
            self.statusbar.showMessage('Noise {:.4f}'.format(noise))
            self.plot_spect(xdata, ydata, fit, baseline)
            data_table = np.column_stack((xdata, ydata, fit, baseline))
            return data_table, popt, uncertainty, ppoly
        else:
            return None, None, None, None

    def load_data(self):        # load data
        # check if there is a file name
        try:
            filename = '/'.join([self.current_dir, self.current_file])
        except AttributeError:
            select_file = QtWidgets.QMessageBox.warning(self, 'No File!',
                'No spectrum file has been selected. Do you want to select now?',
                QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
                QtWidgets.QMessageBox.Yes)
            if select_file == QtWidgets.QMessageBox.Yes:
                self.open_file()
            else:
                self.fit_stat.stat = 2  # exception: file not found
                return None, None
        # try load data
        xdata, ydata, self.fit_stat.stat = sflib.read_file(filename,
                                 self.fit_par.boxwin, self.fit_par.rescale)
        # if file is readable, plot raw data and return xy data
        if not self.fit_stat.stat:
            self.plot_data(xdata, ydata)
            return xdata, ydata
        else:
            return None, None

    def plot_data(self, xdata, ydata):        # plot raw data file before fit
        self.fig.clear()
        ax = self.fig.add_subplot(111)
        ax.hold(False)
        ax.plot(xdata, ydata, 'k-')
        ax.set_xlabel('Frequency (MHz)')
        ax.set_ylabel('Intensity (a.u.)')
        self.canvas.draw()

    def plot_spect(self, xdata, ydata, fit, baseline):       # plot fitted spectra
        self.fig.clear()
        ax = self.fig.add_subplot(111)
        ax.plot(xdata, ydata, 'k-', xdata, fit+baseline, 'r-',
                xdata, baseline, 'b--')
        ax.set_xlabel('Frequency (MHz)')
        ax.set_ylabel('Intensity (a.u.)')
        self.canvas.draw()

    # --------- file handling ---------
    def open_file(self):
        # get all file names
        QFileHandle = QtWidgets.QFileDialog()
        QFileHandle.setDirectory(self.current_dir)
        filelist = QFileHandle.getOpenFileNames(self, 'Open Spectra')[0]
        # if list is not empty, proceed
        if filelist:
            # sort file name
            filelist.sort()
            # seperate directory name and file name
            self.list_dir, self.list_file = sflib.separate_dir(filelist)
            # get the first directory and file name
            self.current_dir = self.list_dir[0]
            self.current_file = self.list_file[0]
            self.fit_stat.file_idx = 0
            # update label
            self.label_current_file.setText(self.current_file)
            # launch fit routine
            self.load_data()
        else:
            self.fit_stat.stat = 2

    def pass_file(self):
        try:
            self.list_aborted_file.append('/'.join([self.current_dir, self.current_file]))
        except AttributeError:
            pass
        self.next_file()

    def save_file(self, data_table, popt, uncertainty, ppoly):
        default_fitname = sflib.out_name_gen(self.current_file) + '.csv'
        default_logname = sflib.out_name_gen(self.current_file) + '.log'
        fitname = QtWidgets.QFileDialog.getSaveFileName(self,
                  'Save Current Fit Spectrum', '/'.join([self.current_dir, default_fitname]))[0]
        if fitname:
            sflib.save_fit(fitname, data_table, popt,
                       self.fit_par.ftype, self.fit_par.der, self.fit_par.peak)
        logname = QtWidgets.QFileDialog.getSaveFileName(self,
                   'Save Current Fit Log', '/'.join([self.current_dir, default_logname]))[0]
        if logname:
            sflib.save_log(logname, popt, uncertainty, ppoly,
                       self.fit_par.ftype, self.fit_par.der,
                       self.fit_par.peak, self.fit_par.par_name)
        self.list_success_file.append('/'.join([self.current_dir, self.current_file]))

    def next_file(self):
        # refresh current file index, fit status and click counter
        self.fit_stat.file_idx += 1
        self.fit_stat.stat = 0
        self.click_counter = 0

        try:
            self.current_file = self.list_file[self.fit_stat.file_idx]
            self.current_dir = self.list_dir[self.fit_stat.file_idx]
            # update label text
            self.label_current_file.setText(self.current_file)
            # repeat fit routine
            self.load_data()
        except (IndexError, AttributeError):
            eof = QtWidgets.QMessageBox.information(self, 'End of File',
                    'No more files to fit. Do you want to select new files?',
                    QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.Close,
                    QtWidgets.QMessageBox.Yes)
            if eof == QtWidgets.QMessageBox.Yes:
                self.open_file()
            else:
                self.close()

    def get_file_dir(self):
        try:
            f = open('.prev_dir.log', 'r')
            last_dir = f.readline()
            f.close()
            return last_dir
        except FileNotFoundError:
            return self.log_dir

    def save_log(self):
        log = QtWidgets.QFileDialog()
        log.setNameFilter('Log files (*.log)')
        logname = log.getSaveFileName(self, 'Save Fit Log',
                            '/'.join([self.current_dir, 'FitJob.log']))[0]
        # if name is not empty
        if logname:
            pass
        else:
            logname = '/'.join([self.log_dir, 'FitJob.log'])

        with open(logname, 'w') as a_log:
            for file_name in self.list_success_file:
                a_log.write('Successful  --- {0:s}\n'.format(file_name))
            for file_name in self.list_aborted_file:
                a_log.write('Aborted     --- {0:s}\n'.format(file_name))

    def save_last_dir(self):
        with open('.prev_dir.log', 'w') as a_file:
            a_file.write(self.current_dir)

    # --------- some useful little tools -----------

    def show_boxcar(self, state):
        if state == QtCore.Qt.Checked:
            self.edit_boxcar.show()
        else:
            # make sure no boxcar (in case)
            self.edit_boxcar.setText('1')
            self.edit_boxcar.hide()

    def show_rescale(self, state):
        if state == QtCore.Qt.Checked:
            self.edit_rescale.show()
        else:
            # no rescale
            self.edit_rescale.setText('1')
            self.edit_rescale.hide()

    def check_double_validity(self, *args):
        sender = self.sender()
        validator = QtGui.QDoubleValidator()
        state = validator.validate(sender.text(), 0)[0]
        if state == QtGui.QValidator.Acceptable and sender.text():
            color = '#00A352'       # green
            self.fit_stat.input_valid = 2    # valid entry
        elif not sender.text():
            color = '#FF9933'       # yellow
            self.fit_stat.input_valid = 1    # empty entry
        else:
            color = '#D63333'       # red
            self.fit_stat.input_valid = 0    # invalid entry
        sender.setStyleSheet('border: 3px solid %s' % color)

    def check_int_validity(self, *args):
        sender = self.sender()
        validator = QtGui.QIntValidator()
        state = validator.validate(sender.text(), 0)[0]
        if state == QtGui.QValidator.Acceptable and sender.text():
            color = '#00A352'       # green
            self.fit_stat.input_valid = 2    # valid entry
        elif not sender.text():
            color = '#FF9933'       # yellow
            self.fit_stat.input_valid = 1    # empty entry
        else:
            color = '#D63333'       # red
            self.fit_stat.input_valid = 0    # invalid entry
        sender.setStyleSheet('border: 3px solid %s' % color)

    def clear_item(self, layout):        # clears all elements in the layout
        if layout is not None:
            while layout.count():
                item = layout.takeAt(0)
                w = item.widget()
                if w is not None:
                    w.deleteLater()
                else:
                    self.clear_item(item.layout())

    def mpl_key_press(self, event):
        # matplotlib standard key press event
        key_press_handler(event, self.canvas, self.mpl_toolbar)

    def mpl_click(self, event):
        # if can still pick peak position
        if (self.click_counter < self.fit_par.peak) and (self.click_counter >= 0):
            # update counter
            self.click_counter += 1
            # retrieve cooridate upon mouse click
            mu = event.xdata    # peak center
            a = event.ydata*0.1   # peak intensity
            # locate parameter index in the parameter list
            mu_idx = self.fit_par.par_per_peak * (self.click_counter-1)
            a_idx = mu_idx + self.fit_par.par_per_peak - 1
            self.edit_par[mu_idx].setText(str(mu))
            self.edit_par[a_idx].setText(str(a))
        elif self.click_counter >= self.fit_par.peak:
            # click number overloads. As user to reset
            reset = QtWidgets.QMessageBox.question(self, 'Reset?',
                       'Do you want to reset clicks to override peak selection?',
                       QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No,
                       QtWidgets.QMessageBox.No)
            if reset == QtWidgets.QMessageBox.Yes:
                self.click_counter = 0
            elif reset == QtWidgets.QMessageBox.No:
                self.click_counter = -1     # no longer bother in this session
        else:
            event.ignore()

    def closeEvent(self, event):   # exit warning
        quit_confirm = QtWidgets.QMessageBox.question(self, 'Quit?',
                       'Are you sure to quit?', QtWidgets.QMessageBox.Yes |
                       QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.Yes)
        if quit_confirm == QtWidgets.QMessageBox.Yes:
            #try:
                # save fit job log file
            self.save_log()
            self.save_last_dir()
            #except:
            #    pass
            event.accept()
        else:
            event.ignore()

    def keyPressEvent(self, event): # press ESC to exit
        if event.key() == QtCore.Qt.Key_Escape:
            self.close()
Beispiel #60
0
class plot_window():
    def __init__(self):
        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure)
        self.toolbar = NavigationToolbar(self.canvas, self)

    def plot(self, conc, data, samplename, blankstdev, sampleMW):
        self.figure.clear()

        ax = self.figure.add_subplot(111)
        ax.clear()

        logconc = [np.log10(x) for x in conc]  # log(concentration)

        if samplename == '':
            samplename = "sample"

        data = [abs(d) for d in data]  #absolute value of data

        ax.scatter(logconc, data, marker='s', label=samplename, c="k")
        ax.set(ylabel=r'$\Delta$ I / I$_0$',
               xlabel="log [concentration (g/mL) ]")
        ax.set_ylim(auto=True)
        ax.set_xlim(auto=True)

        ax.legend(loc='upper left')

        if len(data) > 1:
            # Trendline plot
            equation = self._trendline(logconc, data)
            # get data stats
            slope, intercept, r_value, Rsquare = self.get_stats(logconc, data)
            # get LOD
            LOD_for_mM, LOD_for_gmL = self.get_LOD(blankstdev, slope,
                                                   intercept, sampleMW)
            # table in fig
            self.table(equation, samplename, intercept, slope, r_value,
                       Rsquare, LOD_for_mM, LOD_for_gmL, sampleMW)

        self.canvas.draw()
        return logconc

    def _trendline(self, conc, data):
        z = np.polyfit(conc, data, 1)
        p = np.poly1d(z)

        y_hat = p(conc)
        plt.plot(conc, y_hat, "r", linewidth=.8)
        equation = "y = %.4fx + ( %.4f )" % (z[0], z[1])

        return equation

    def get_stats(self, conc, data):
        slope, intercept, r_value, p_value, std_err = stats.linregress(
            conc, data)

        return slope, intercept, r_value, r_value**2

    def get_LOD(self, blankstdev, slope, intercept, sampleMW):
        index = ((3 * blankstdev) - intercept) / slope
        LOD_for_M = (10**index) / sampleMW
        LOD_for_gmL = 10**index
        return LOD_for_M, LOD_for_gmL

    def table(self, equation, plot_sample, intercept, slope, Pearsons_r,
              r_square_value, LOD_for_M, LOD_for_gmL, sampleMW):
        # col_labels = ['']
        row_labels = [
            'Equation', 'Plot', 'Intercept', 'Slope', "Pearson's r",
            "R-square", "sample M.W.", "LOD(M)", "LOD(g/mL)"
        ]
        table_vals = [
            [equation],
            [plot_sample],
            ["%.4f" % intercept],
            ["%.4f" % slope],
            ["%.4f" % Pearsons_r],
            ["%.4f" % r_square_value],
            ["%.2f Kda" % sampleMW],
            ["%.3E (M)" % LOD_for_M],
            ["%.3E (g/mL)" % LOD_for_gmL],
        ]
        fig_table = plt.table(cellText=table_vals,
                              colWidths=[0.2] * 1,
                              rowLabels=row_labels,
                              colLabels=None,
                              loc='lower right')
        fig_table.set_fontsize(15.0)