class GUI:
    def __init__(self):
        self.b = Gtk.Builder()
        gui_xml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)),
                                    'calibrate_camera_extrinsics_gui.xml')
        self.b.add_from_file(gui_xml_path)
        self.window = self.b.get_object("window")
        self.window.set_title('CamExtrinsicCalibrator')

        self.f = matplotlib.figure.Figure()
        self.ax = self.f.add_subplot(111)
        self.f.subplots_adjust(left=0.01,
                               right=0.99,
                               bottom=0.01,
                               top=0.99,
                               hspace=0,
                               wspace=0)

        self.canvas = FigureCanvas(self.f)
        self.b.get_object("alignment_img").add(self.canvas)
        self.image_display_mode = None
        self.window.show_all()

    def display_image(self, model):
        label = self.b.get_object("label_image")
        label.set_text(model.image_path)

        img = model.get_image(self.image_display_mode)
        if len(img.shape) == 2:
            img2 = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)
        else:
            img2 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        self.ax.imshow(img2)
        self.canvas.draw()
示例#2
0
class PlotCanvas(object):
    def __init__(self, title, label, unit, color):
        # super(PlotCanvas, self).__init__()
        self.fig = Figure()
        self.ax = self.fig.add_subplot(111)

        self.ax.set_title(title)
        self.ax.grid(True)

        self.canvas = FigureCanvas(self.fig)
        self.canvas.set_size_request(400, 300)
        self.canvas.show()

        self.data = []
        self.line, = self.ax.plot([], self.data)
        self.line.set_label(label)
        self.line.set_color(color)
        # self.ax.set_xlabel("# de Muestras")
        # self.ax.set_ylabel(f"[{unit}]")
        self.ax.legend(loc='upper right')

    def update_draw(self, *args):
        # print(args[0])
        self.data.append(args[0])
        # print(self.data)
        self.line.set_data(range(len(self.data)), self.data)
        # self.l_data.set_ydata(self.data)
        self.ax.relim()
        self.ax.autoscale_view(True, True, True)
        # print(self.l_data)
        try:
            self.canvas.draw()
        except Exception as e:
            print(e)
示例#3
0
class Map:
    def __init__(self, viewport: Gtk.Viewport):
        self._viewport = viewport

        figure = Figure()
        self._canvas = FigureCanvas(figure)
        self._viewport.add(self._canvas)
        self._viewport.show_all()

    def draw_cities(self, cities, tour=False):
        x = np.array([city.x for city in cities], dtype=np.float)
        y = np.array([city.y for city in cities], dtype=np.float)

        figure = self._canvas.figure

        axis = figure.subplots(1, 1)
        axis.get_xaxis().set_visible(False)
        axis.get_yaxis().set_visible(False)

        axis.clear()

        axis.scatter(x, y, color='red', linewidth=0.5)

        if tour:
            x = np.append(x, x[0])
            y = np.append(y, y[0])
            axis.plot(x, y, linewidth=0.5)

        self._canvas.draw()
示例#4
0
class History:
    def __init__(self, viewport):
        self._viewport = viewport

        figure = Figure()
        self._canvas = FigureCanvas(figure)
        self._viewport.add(self._canvas)
        self._viewport.show_all()

    def draw(self, ga_history, pso_history):
        x_ga = np.array([i + 1 for i in range(len(ga_history))], dtype=np.int)
        y_ga = np.array(ga_history, dtype=np.float)

        x_pso = np.array([i + 1 for i in range(len(pso_history))],
                         dtype=np.int)
        y_pso = np.array(pso_history, dtype=np.float)

        figure = self._canvas.figure

        axis = figure.subplots(1, 1)
        axis.clear()
        ga, = axis.plot(x_ga, y_ga)
        pso, = axis.plot(x_pso, y_pso)
        axis.legend((ga, pso), ('GA', 'PSO'))

        self._canvas.draw()
        time.sleep(1e-2)
        try:
            figure.clf()
        except:
            pass
class Plot(Gtk.Frame):
    def __init__(self, sp, refs):
        Gtk.Frame.__init__(self)
        self.f = Figure()
        self.canvas = FigureCanvas(self.f)
        self.add(self.canvas)
        self.set_size_request(1024, 600)
        self.f.subplots_adjust(left=0.07, right=0.98, bottom=0.05, top=0.95,
                               hspace=0.2, wspace=0.2)
        # self.buffer = self.canvas.get_snapshot()

    def decorate(self, axis, title=None, ylab=None, legend=None):
        # font_prop = fm.FontProperties(fname='Humor-Sans-1.0.ttf', size=14)
        if title is not None:
            axis.set_title(title)  # , fontproperties=font_prop)
        if ylab is not None:
            axis.yaxis.set_label_text(ylab)  # , fontproperties=font_prop)
        if legend is not None:
            axis.legend(legend)  # , prop=font_prop)
        axis.xaxis.grid(color='k', linestyle='-', linewidth=0.2)
        axis.yaxis.grid(color='k', linestyle='-', linewidth=0.2)

    def update(self, sp, refs):
        title = [r'$\phi$', r'$\theta$', r'$\psi$']
        legend = ['Ref1', 'Ref2', 'Setpoint']
        for i in range(0, 3):
            axis = self.f.add_subplot(331 + i)
            axis.clear()
            for ref in refs:
                axis.plot(sp.time, pu.deg_of_rad(ref.euler[:, i]))
            axis.plot(sp.time, pu.deg_of_rad(sp.euler[:, i]))
            self.decorate(axis, title[i], *(('deg', legend) if i == 0 else (None, None)))

        title = [r'$p$', r'$q$', r'$r$']
        for i in range(0, 3):
            axis = self.f.add_subplot(334 + i)
            axis.clear()
            for ref in refs:
                axis.plot(sp.time, pu.deg_of_rad(ref.vel[:, i]))
            self.decorate(axis, title[i], 'deg/s' if i == 0 else None)

        title = [r'$\dot{p}$', r'$\dot{q}$', r'$\dot{r}$']
        for i in range(0, 3):
            axis = self.f.add_subplot(337 + i)
            axis.clear()
            for ref in refs:
                axis.plot(sp.time, pu.deg_of_rad(ref.accel[:, i]))
            self.decorate(axis, title[i], 'deg/s2' if i == 0 else None)

        self.canvas.draw()
示例#6
0
class ResidualsPlotView(View['ResidualsPlotPresenter', Gtk.Widget]):
    def _do_init(self) -> Gtk.Widget:
        from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas
        from matplotlib.figure import Figure

        self._widget = Gtk.Grid()

        figure = Figure(tight_layout=True)

        self._figure_canvas = FigureCanvas(figure)
        self._figure_canvas.props.hexpand = True
        self._figure_canvas.props.vexpand = True
        self._figure_canvas.show()
        self._widget.add(self._figure_canvas)

        self._axes = figure.add_subplot(1, 1, 1)

        # Set tick labels font size
        for item in (*self._axes.get_xticklabels(),
                     *self._axes.get_yticklabels()):
            item.set_fontsize(8)

        self.presenter.view_ready()

        return self._widget

    def set_data(self, residuals: np.ndarray) -> None:
        axes = self._axes
        axes.clear()

        if residuals is None or len(residuals) == 0:
            axes.set_axis_off()
            self._figure_canvas.draw()
            return

        axes.set_axis_on()
        axes.plot(residuals[:, 0],
                  residuals[:, 1],
                  color='#0080ff',
                  marker='o',
                  linestyle='')
        self._figure_canvas.draw()

    def _do_destroy(self) -> None:
        self._widget.destroy()
示例#7
0
文件: img.py 项目: ke8ctn/gtknodes
class ImgPltNode(GtkNodes.Node):
    __gtype_name__ = 'PltNode'

    def __init__(self, *args, **kwds):
        super().__init__(*args, **kwds)

        self.set_label("Image Plot")
        self.connect("node_func_clicked", self.remove)

        # create input socket
        lbl = Gtk.Label.new("Input")
        lbl.set_xalign(0.0)
        node_socket_input = self.item_add(lbl, GtkNodes.NodeSocketIO.SINK)
        node_socket_input.connect("socket_incoming", self.node_socket_incoming)

        # the compatibility key
        node_socket_input.set_key(1234)
        node_socket_input.set_rgba(get_rgba('darkturquoise'))

        f = Figure(figsize=(5, 4), dpi=100)
        self.a = f.add_subplot(111)

        sw = Gtk.ScrolledWindow()
        sw.set_border_width(10)

        self.canvas = FigureCanvas(f)
        sw.add(self.canvas)
        sw.set_size_request(200, 200)

        self.item_add(sw, GtkNodes.NodeSocketIO.DISABLE)
        self.set_child_packing(sw, True, True, 0, Gtk.PackType.END)

    def node_socket_incoming(self, socket, payload):

        img = pickle.loads(payload)

        self.a.imshow(img)
        self.canvas.draw()

    def remove(self, node):
        self.destroy()
class OdPredictorGui(Gtk.HBox):

    def __init__(self):
        super().__init__()
        self.controls = ControlPanel()
        self.controls.connect('new-params', self.on_new_params)

        self.fig = Figure(facecolor='#e9e9e9')
        self.axes = self.fig.add_subplot(1, 1, 1)
        self.canvas = FigureCanvas(self.fig)
        self.canvas.set_size_request(300, 300)

        self.pack_start(self.controls, False, False, 0)
        self.pack_start(self.canvas, True, True, 0)

        self.on_new_params()

    def on_new_params(self, *args):
        predictor = self.controls.get_params()
        predictor.plot_time_estimate(self.axes)
        self.fig.tight_layout(pad=1.0)
        self.canvas.draw()
示例#9
0
class PopUpImage(object):
	def __init__(self, xdata, ydata, xlabel, ylabel, title):
		self.popupwin=Gtk.Window()
		self.popupwin.set_size_request(600,550)
		self.popupwin.set_position(Gtk.WindowPosition.CENTER)
		self.popupwin.set_border_width(10)
		self.xdata = xdata
		self.ydata = ydata
		vbox = Gtk.VBox()
		self.fig=Figure(dpi=100)
		self.ax  = self.fig.add_subplot(111)
		self.canvas  = FigureCanvas(self.fig)
		self.main_figure_navBar = NavigationToolbar(self.canvas, self)
		self.cursor = Cursor(self.ax, color='k', linewidth=1, useblit=True)
		self.canvas.mpl_connect("button_press_event",self.on_press)
		self.ax.set_xlabel(xlabel, fontsize = 18)
		self.ax.set_ylabel(ylabel, fontsize = 18)
		self.ax.set_title(title, fontsize = 18)
		self.ax.plot(self.xdata, self.ydata, 'b-', lw=2)
		
		self.textes = []
		self.plots  = []
		vbox.pack_start(self.main_figure_navBar, False, False, 0)
		vbox.pack_start(self.canvas, True, True, 2)
		self.popupwin.add(vbox)
		self.popupwin.connect("destroy", self.dest)
		self.popupwin.show_all()
	
	def dest(self,widget):
		self.popupwin.destroy()
	
	def on_press(self, event):
		if event.inaxes == self.ax and event.button==3:
			self.clear_notes()
			xc = event.xdata
			#***** Find the closest x value *****
			residuel = self.xdata - xc
			residuel = N.abs(residuel)
			j = N.argmin(residuel)
			#y = self.ydata[i-1:i+1]
			#yc= y.max()
			#j = N.where(self.ydata == yc)
			#j = j[0][0]
			xc= self.xdata[j]
			x_fit = self.xdata[j-3:j+3]
			y_fit = self.ydata[j-3:j+3]
			fitted_param, fitted_data = fit(x_fit, y_fit, xc, True)
			x_fit = N.linspace(x_fit.min(), x_fit.max(), 200)
			y_fit = psdVoigt(fitted_param, x_fit)
			period = fitted_param['xc'].value
			std_err= fitted_param['xc'].stderr
			
			p = self.ax.plot(x_fit, y_fit,'r-')
			p2 = self.ax.axvline(period,color='green',lw=2)
			
			txt=self.ax.text(0.05, 0.9, 'Period = %.4f +- %.4f (nm)'%(period, std_err), transform = self.ax.transAxes, color='red')
			self.textes.append(txt)
			self.plots.append(p[0])
			self.plots.append(p2)
		elif event.inaxes == self.ax and event.button==2:
			dif = N.diff(self.ydata)
			dif = dif/dif.max()
			p3  = self.ax.plot(dif,'r-')
			self.plots.append(p3[0])
		self.canvas.draw()
	
	def clear_notes(self):
		if len(self.textes)>0:
			for t in self.textes:
				t.remove()
		if len(self.plots)>0:
			for p in self.plots:
				p.remove()
		self.textes = []
		self.plots  = []
示例#10
0
class KMeans(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self)
        self.set_title("k srednich")
        self.connect('destroy', Gtk.main_quit)
        self.main_view = Gtk.HBox()
        self.plot_view = Gtk.VBox()
        self.box = Gtk.VBox(homogeneous=False, spacing=0)
        self.filew = ""
        button1 = Gtk.Button("Wybierz plik")
        button1.connect("clicked", self.on_file_clicked)
        self.box.add(button1)

        reset_button = Gtk.Button("Resetuj")
        reset_button.connect("clicked", self.reset)
        self.box.add(reset_button)

        self.cluster_label = Gtk.Label("Liczba skupien:")
        self.box.add(self.cluster_label)

        adjustment = Gtk.Adjustment(1, 1, 20, 1, 1, 0)
        self.h_scale = Gtk.Scale(
            orientation=Gtk.Orientation.HORIZONTAL, adjustment=adjustment)
        self.h_scale.set_digits(0)
        self.h_scale.set_hexpand(True)
        self.h_scale.set_valign(Gtk.Align.START)
        self.h_scale.connect("value-changed", self.scale_moved)
        self.box.add(self.h_scale)

        metric_label = Gtk.Label("Wybierz rodzaj metryki:")

        name_store = Gtk.ListStore(int, str)
        name_store.append([1, "Euklidesowa"])
        name_store.append([2, "Miejska"])
        name_combo = Gtk.ComboBox.new_with_model_and_entry(name_store)
        name_combo.connect("changed", self.on_name_combo_changed)
        name_combo.set_entry_text_column(1)

        self.box.add(metric_label)
        self.box.add(name_combo)
        self.centroid_button = Gtk.Button("Wybierz centroidy")
        self.centroid_button.set_sensitive(False)
        self.centroid_button.connect("clicked", self.run_kmeans)

        self.group_button = Gtk.Button("Grupuj")
        self.group_button.set_sensitive(False)
        self.group_button.connect("clicked", self.group)


        self.scale_plot = Gtk.Button("Skaluj")
        self.scale_plot.set_sensitive(False)
        self.scale_plot.connect("clicked", self.scaled)


        self.box.add(self.centroid_button)
        self.box.add(self.group_button)
        self.box.add(self.scale_plot)
        self.data = ""
        self.cluster_count = ""
        self.metric_id = ""
        self.filename = ""
        self.plot_area = ""
        self.cluster = ""
        self.color_random = ""
        self.figure = ""
        self.cluster_centers = []
        self.plot_canvas = ""
        self.main_data_canvas = ""

        self.main_view.add(self.box)
        self.main_view.add(self.plot_view)
        self.add(self.main_view)
        self.couting = 0
        self.is_random_center = 0

        self.show_all()

    def scaled(self, event):
        plt.scatter(*zip(*self.data), c=self.color_random[self.cluster])
        plt.scatter(*zip(*self.cluster_centers), s=500, c=self.color_random, marker='v')
        plt.show()

    def run_kmeans(self, event):
        self.kmeans(self.cluster_count, self.data)

    def group(self, event):
        self.couting += 1

        if self.couting % 2 == 0:
            print "Parzysta"
            self.kmeans(self.cluster_count, self.data)
            # self.plot_area.scatter(*zip(*self.data))
            self.plot_area.clear()
            self.plot_area.scatter(*zip(*self.data))
            self.plot_area.scatter(*zip(*self.cluster_centers), s=500, c=self.color_random, marker='v')
            self.plot_canvas.draw()
            self.plot_view.show_all()

        else:
            print "Nieparzysta"

            self.plot_area.scatter(*zip(*self.data), c=self.color_random[self.cluster])
            self.plot_area.scatter(*zip(*self.cluster_centers), s=500, c=self.color_random, marker='v')
            self.plot_canvas.draw()
            self.plot_view.show_all()


    def on_name_combo_changed(self, combo):
        tree_iter = combo.get_active_iter()
        if tree_iter != None:
            model = combo.get_model()
            row_id, name = model[tree_iter][:2]
            self.metric_id = row_id
            # 1 euklidesowa
            # 2 miejsca
            print("Selected: ID=%d, name=%s" % (row_id, name))
        else:
            entry = combo.get_child()
            print("Entered: %s" % entry.get_text())

    def scale_moved(self, event):
        self.cluster_count = self.h_scale.get_value()

    def on_file_clicked(self, widget):
        print "clikc"
        dialog = Gtk.FileChooserDialog("Please choose a file", self,
                                       Gtk.FileChooserAction.OPEN,
                                       (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                                        Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            print("Open clicked")
            print("File selected: " + dialog.get_filename())
            self.filename = dialog.get_filename()
            dialog.destroy()
            self.openfile(self.filename)

        elif response == Gtk.ResponseType.CANCEL:
            print("Cancel clicked")

    def openfile(self, filename):

        with open(filename) as csvfile:
            self.data = [(float(x), float(y)) for x, y in csv.reader(csvfile, delimiter=",")]

        self.load_data_from_file()

    def load_data_from_file(self):
        self.centroid_button.set_sensitive(True)
        self.group_button.set_sensitive(True)
        self.scale_plot.set_sensitive(True)

        f = Figure(figsize=(5, 4), dpi=100)
        a = f.add_subplot(111)
        a.scatter(*zip(*self.data))
        self.main_data_canvas = FigureCanvas(f)
        self.plot_view.add(self.main_data_canvas)
        self.plot_view.show_all()
        self.resize(1000,400)

    def euclides_distance(self, p1, p2):
        dist = 0.0
        for i in xrange(0, len(p2)):
            dist += (p1[i] - p2[i]) ** 2
        return math.sqrt(dist)

    def manhattan_distance(self, x, y):

        return sum(abs(a - b) for a, b in zip(x, y))

    def kmeans(self, k, data):
        self.color_random = np.arange(k)

        # wymiar danych
        dim = len(data[0])

        # lista zer
        cluster = [0] * len(data)
        # lista -1
        prev_cluster = [-1] * len(data)

        i = 0
        max_iter = 1000

        if self.is_random_center == 0:
            for i in xrange(0, int(k)):
                self.cluster_centers += [random.choice(data)]

            self.is_random_center = 1

        # while (cluster != prev_cluster) or i > max_iter:
        prev_cluster = list(cluster)
        i += 1
        print "Iteracja numer"
        # print "Cluster {}".format(cluster)

        for x in xrange(0, len(data)):
            min_dist = float("inf")

            # sprawdzenie minimalnego dystansu miedzy srodkami
            for y in xrange(0, len(self.cluster_centers)):
                distance = ""
                if self.metric_id == 2:
                    distance = self.manhattan_distance(data[x], self.cluster_centers[y])
                else:
                    distance = self.euclides_distance(data[x], self.cluster_centers[y])

                if distance < min_dist:
                    min_dist = distance
                    cluster[x] = y

        # aktualizacja srodkow
        for k in xrange(0, len(self.cluster_centers)):
            new_center = dim * [0]
            members = 0
            for p in xrange(0, len(data)):
                if cluster[p] == k:  # ten punkt nalezy do klastra
                    for j in xrange(0, dim):
                        new_center[j] += data[p][j]
                        # print "Nowy srodek {}".format(new_center[j])
                    members += 1

            for j in xrange(0, dim):
                if members != 0:
                    new_center[j] = new_center[j] / float(members)

            self.cluster_centers[k] = new_center

        print self.cluster_centers

        self.cluster = cluster

        if self.couting == 0:
            print "Rysuje"
            self.figure = Figure(figsize=(5, 4), dpi=100)
            self.plot_area = self.figure.add_subplot(111)
            self.plot_area.scatter(*zip(*data))
            self.plot_area.scatter(*zip(*self.cluster_centers), s=500, c=self.color_random, marker='v')
            self.plot_canvas = FigureCanvas(self.figure)
            self.plot_canvas.draw()
            self.plot_canvas.show_all()
            self.plot_view.add(self.plot_canvas)
            self.plot_view.show()
            self.plot_view.show_all()

    def reset(self, event):
        self.plot_view.remove(self.plot_canvas)
        self.plot_view = Gtk.VBox()
        self.plot_view.show_all()
        self.couting = 0
        self.is_random_center = 0
示例#11
0
class LockinGui(object):
    _window_title = "Lock-in Spectrum"
    _heartbeat = 100  # ms delay at which the plot/gui is refreshed, and the gamepad moves the stage

    def __init__(self):
        self.savedir = "./Spectra/"
        self.path = "./"

        self.settings = Settings()

        self.x_step = .0
        self.y_step = .0
        self.step_distance = 1  # in um

        try:
            self.stage = PIStage.E545(self.settings.stage_ip,self.settings.stage_port)
        except:
            self.stage = None
            self.stage = PIStage.Dummy()
            print("Could not initialize PIStage, using Dummy instead")

        GObject.threads_init()
        # only GObject.idle_add() is in the background thread
        self.window = Gtk.Window(title=self._window_title)
        # self.window.set_resizable(False)
        self.window.set_border_width(3)

        self.grid = Gtk.Grid()
        self.grid.set_row_spacing(5)
        self.grid.set_column_spacing(5)
        self.window.add(self.grid)

        # Buttons for spectrum stack
        self.button_live = Gtk.Button(label="Liveview")
        self.button_live.set_tooltip_text("Start/Stop Liveview of Spectrum")
        self.button_stop = Gtk.Button(label="Stop")
        self.button_stop.set_tooltip_text("Stop any ongoing Action")
        self.button_stop.set_sensitive(False)
        self.button_aquire = Gtk.Button(label="Aquire Spectrum")
        self.button_aquire.set_tooltip_text("Start/Stop aquiring Lock-In Spectrum")
        self.button_direction = Gtk.Button(label="Set Direction")
        self.button_direction.set_tooltip_text("Set Direction of Stage Movement")
        self.button_settings = Gtk.Button(label="Settings")
        self.button_settings.set_tooltip_text("Set Integration Time and Number of Samples")
        self.button_search = Gtk.Button(label="Search for Max")
        self.button_search.set_tooltip_text("Search for position with maximum Intensity")
        self.button_save = Gtk.Button(label="Save Data")
        self.button_save.set_tooltip_text("Save all spectral Data in .csv")
        self.button_dark = Gtk.Button(label="Take Dark Spectrum")
        self.button_dark.set_tooltip_text("Take dark spectrum which will substracted from spectrum")
        self.button_lamp = Gtk.Button(label="Take Lamp Spectrum")
        self.button_lamp.set_tooltip_text("Take lamp spectrum to normalize spectrum")
        self.button_normal = Gtk.Button(label="Take Normal Spectrum")
        self.button_normal.set_tooltip_text("Start/Stop taking a normal spectrum")
        self.button_bg = Gtk.Button(label="Take Background Spectrum")
        self.button_bg.set_tooltip_text("Start/Stop taking a Background spectrum")
        self.button_series = Gtk.Button(label="Take Time Series")
        self.button_series.set_tooltip_text("Start/Stop taking a Time Series of Spectra")
        self.button_reset = Gtk.Button(label="Reset")
        self.button_reset.set_tooltip_text("Reset all spectral data (if not saved data is lost!)")
        self.button_loaddark = Gtk.Button(label="Load Dark Spectrum")
        self.button_loaddark.set_tooltip_text("Load Dark Spectrum from file")
        self.button_loadlamp = Gtk.Button(label="Load Lamp Spectrum")
        self.button_loadlamp.set_tooltip_text("Load Lamp Spectrum from file")

        # Stage Control Buttons
        self.button_xup = Gtk.Button(label="x+")
        self.button_xdown = Gtk.Button(label="x-")
        self.button_yup = Gtk.Button(label="y+")
        self.button_ydown = Gtk.Button(label="y-")
        self.button_zup = Gtk.Button(label="z+")
        self.button_zdown = Gtk.Button(label="z-")
        self.button_stepup = Gtk.Button(label="+")
        self.button_stepdown = Gtk.Button(label="-")
        self.label_stepsize = Gtk.Label(label=str(self.settings.stepsize))
        self.button_moverel = Gtk.Button(label="Move Stage rel.")
        self.button_moveabs = Gtk.Button(label="Move Stage abs.")
        # Stage position labels
        self.label_x = Gtk.Label()
        self.label_y = Gtk.Label()
        self.label_z = Gtk.Label()
        self.show_pos()

        # Connect Buttons
        self.window.connect("delete-event", self.quit)
        self.button_aquire.connect("clicked", self.on_lockin_clicked)
        self.button_direction.connect("clicked", self.on_direction_clicked)
        self.button_live.connect("clicked", self.on_live_clicked)
        self.button_stop.connect("clicked", self.on_stop_clicked)
        self.button_settings.connect("clicked", self.on_settings_clicked)
        self.button_search.connect("clicked", self.on_search_clicked)
        self.button_save.connect("clicked", self.on_save_clicked)
        self.button_dark.connect("clicked", self.on_dark_clicked)
        self.button_lamp.connect("clicked", self.on_lamp_clicked)
        self.button_normal.connect("clicked", self.on_normal_clicked)
        self.button_bg.connect("clicked", self.on_bg_clicked)
        self.button_series.connect("clicked", self.on_series_clicked)
        self.button_reset.connect("clicked", self.on_reset_clicked)
        self.button_loaddark.connect("clicked", self.on_loaddark_clicked)
        self.button_loadlamp.connect("clicked", self.on_loadlamp_clicked)
        # Connect Stage Control Buttons
        self.button_xup.connect("clicked", self.on_xup_clicked)
        self.button_xdown.connect("clicked", self.on_xdown_clicked)
        self.button_yup.connect("clicked", self.on_yup_clicked)
        self.button_ydown.connect("clicked", self.on_ydown_clicked)
        self.button_zup.connect("clicked", self.on_zup_clicked)
        self.button_zdown.connect("clicked", self.on_zdown_clicked)
        self.button_stepup.connect("clicked", self.on_stepup_clicked)
        self.button_stepdown.connect("clicked", self.on_stepdown_clicked)
        self.button_moverel.connect("clicked", self.on_moverel_clicked)
        self.button_moveabs.connect("clicked", self.on_moveabs_clicked)

        # Stage Control Button Table
        self.table_stagecontrol = Gtk.Table(3, 4, True)
        self.table_stagecontrol.attach(self.button_xup, 0, 1, 1, 2)
        self.table_stagecontrol.attach(self.button_xdown, 2, 3, 1, 2)
        self.table_stagecontrol.attach(self.button_yup, 1, 2, 0, 1)
        self.table_stagecontrol.attach(self.button_ydown, 1, 2, 2, 3)
        self.table_stagecontrol.attach(self.button_zup, 3, 4, 0, 1)
        self.table_stagecontrol.attach(self.button_zdown, 3, 4, 2, 3)
        # Stage Stepsize Table
        self.table_stepsize = Gtk.Table(1, 3, True)
        self.table_stepsize.attach(self.button_stepup, 0, 1, 0, 1)
        self.table_stepsize.attach(self.label_stepsize, 1, 2, 0, 1)
        self.table_stepsize.attach(self.button_stepdown, 2, 3, 0, 1)

        self.status = Gtk.Label(label="Initialized")
        self.progress = Gtk.ProgressBar()
        self._progress_fraction = 0
        self.progress.set_fraction(self._progress_fraction)

        # Box for control of taking single spectra
        self.SpectrumBox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=3)
        self.SpectrumBox.add(Gtk.Separator())
        self.SpectrumBox.add(self.button_live)
        self.SpectrumBox.add(Gtk.Separator())
        self.SpectrumBox.add(Gtk.Label("Lock-In Spectrum"))
        self.SpectrumBox.add(self.button_aquire)
        self.SpectrumBox.add(self.button_direction)
        self.SpectrumBox.add(Gtk.Separator())
        self.SpectrumBox.add(Gtk.Label(label="Additional Spectra"))
        self.SpectrumBox.add(self.button_dark)
        self.SpectrumBox.add(self.button_lamp)
        self.SpectrumBox.add(self.button_normal)
        self.SpectrumBox.add(self.button_bg)
        self.SpectrumBox.add(self.button_series)
        self.SpectrumBox.add(Gtk.Separator())
        self.SpectrumBox.add(Gtk.Label(label="Miscellaneous"))
        self.SpectrumBox.add(self.button_save)
        self.SpectrumBox.add(self.button_settings)
        self.SpectrumBox.add(self.button_reset)
        self.SpectrumBox.add(self.button_loaddark)
        self.SpectrumBox.add(self.button_loadlamp)
        self.SpectrumBox.add(Gtk.Separator())

        # Switch corrected Spectrum yes/no
        self.button_corronoff = Gtk.Switch()
        self.label_corronoff = Gtk.Label('Correct Spectrum')
        self.corronoff_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=3)
        self.corronoff_box.set_homogeneous(True)
        self.corronoff_box.add(self.label_corronoff)
        self.corronoff_box.add(self.button_corronoff)

        # box for Stage control
        self.stage_hbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=3)
        # self.stage_hbox.add(Gtk.Separator())
        self.stage_hbox.add(self.corronoff_box)
        self.stage_hbox.add(self.button_search)
        self.stage_hbox.add(Gtk.Label(label="Stage Control"))
        self.stage_hbox.add(self.table_stagecontrol)
        self.stage_hbox.add(Gtk.Label(label="Set Stepsize [um]"))
        self.stage_hbox.add(self.table_stepsize)
        self.stage_hbox.add(self.button_moverel)
        self.stage_hbox.add(self.button_moveabs)
        self.labels_hbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=3)
        self.labels_hbox.add(self.label_x)
        self.labels_hbox.add(self.label_y)
        self.labels_hbox.add(self.label_z)


        # Buttons for scanning stack
        self.button_add_position = Gtk.Button('Add Position to List')
        self.button_spangrid = Gtk.Button('Span Grid')
        self.button_searchonoff = Gtk.Switch()
        self.label_searchonoff = Gtk.Label('Search Max.')
        self.searchonoff_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=3)
        self.searchonoff_box.set_homogeneous(True)
        self.searchonoff_box.add(self.label_searchonoff)
        self.searchonoff_box.add(self.button_searchonoff)
        self.button_lockinonoff = Gtk.Switch()
        self.label_lockinonoff = Gtk.Label('Use Lock-In')
        self.lockinonoff_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=3)
        self.lockinonoff_box.set_homogeneous(True)
        self.lockinonoff_box.add(self.label_lockinonoff)
        self.lockinonoff_box.add(self.button_lockinonoff)
        self.button_scan_start = Gtk.Button('Start Scan')
        self.scan_hbox = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=3)
        self.button_scan_add = Gtk.ToolButton(Gtk.STOCK_ADD)
        self.button_scan_remove = Gtk.ToolButton(Gtk.STOCK_REMOVE)
        self.button_scan_clear = Gtk.ToolButton(Gtk.STOCK_DELETE)
        self.scan_hbox.set_homogeneous(True)
        self.scan_hbox.add(self.button_scan_add)
        self.scan_hbox.add(self.button_scan_remove)
        self.scan_hbox.add(self.button_scan_clear)


        # Treeview for showing/settings scanning grid
        self.scan_store = Gtk.ListStore(float, float)
        self.scan_view = Gtk.TreeView(model=self.scan_store)
        self.scan_xrenderer = Gtk.CellRendererText()
        self.scan_xrenderer.set_property("editable", True)
        self.scan_xcolumn = Gtk.TreeViewColumn("x", self.scan_xrenderer, text=0)
        self.scan_xcolumn.set_min_width(100)
        self.scan_xcolumn.set_alignment(0.5)
        self.scan_view.append_column(self.scan_xcolumn)

        self.scan_yrenderer = Gtk.CellRendererText()
        self.scan_yrenderer.set_property("editable", True)
        self.scan_ycolumn = Gtk.TreeViewColumn("y", self.scan_yrenderer, text=1)
        self.scan_ycolumn.set_min_width(100)
        self.scan_ycolumn.set_alignment(0.5)
        self.scan_view.append_column(self.scan_ycolumn)

        self.scan_scroller = Gtk.ScrolledWindow()
        self.scan_scroller.set_vexpand(True)
        self.scan_scroller.add(self.scan_view)

        self.scan_store.append([10.0, 10.0])
        self.scan_store.append([10.1, 10.0])
        self.scan_store.append([10.0, 10.1])


        #Connections for scanning stack
        self.button_add_position.connect("clicked", self.on_add_position_clicked)
        self.button_spangrid.connect("clicked", self.on_spangrid_clicked)
        self.button_scan_start.connect("clicked", self.on_scan_start_clicked)
        self.button_scan_add.connect("clicked", self.on_scan_add)
        self.button_scan_remove.connect("clicked", self.on_scan_remove)
        self.button_scan_clear.connect("clicked", self.on_scan_clear)
        self.scan_xrenderer.connect("edited", self.on_scan_xedited)
        self.scan_yrenderer.connect("edited", self.on_scan_yedited)

        #Box for control of scanning
        self.ScanningBox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=3)
        self.ScanningBox.add(Gtk.Separator())
        self.ScanningBox.add(self.button_add_position)
        self.ScanningBox.add(self.button_spangrid)
        self.ScanningBox.add(self.searchonoff_box)
        self.ScanningBox.add(self.lockinonoff_box)
        self.ScanningBox.add(Gtk.Separator())
        self.ScanningBox.add(Gtk.Label("Scanning Positions"))
        self.ScanningBox.add(self.scan_hbox)
        self.ScanningBox.add(self.scan_scroller)
        self.ScanningBox.add(Gtk.Separator())
        self.ScanningBox.add(self.button_scan_start)


        # MPL stuff
        self.figure = Figure()
        self.ax = self.figure.add_subplot(1, 1, 1)
        self.ax.grid(True)
        self.ax.set_xlabel("Wavelength [nm]")
        self.ax.set_ylabel("Intensity")
        self.ax.set_xlim([400, 900])
        self.canvas = FigureCanvas(self.figure)
        self.canvas.set_hexpand(True)
        self.canvas.set_vexpand(True)

        self.canvas.set_size_request(700, 700)

        self.stack = Gtk.Stack()
        self.stack.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT)
        self.stack.set_transition_duration(500)

        self.stack.add_titled(self.SpectrumBox, "spec", "Spectra")
        self.stack.add_titled(self.ScanningBox, "scan", "Scanning")

        self.stack_switcher = Gtk.StackSwitcher()
        self.stack_switcher.set_stack(self.stack)

        self.SideBox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=3)
        self.SideBox.add(self.stack_switcher)
        self.ScanningBox.add(Gtk.Separator())
        self.SideBox.add(self.button_stop)
        self.SideBox.add(self.stack)
        self.SideBox.add(self.stage_hbox)
        self.SideBox.add(self.labels_hbox)

        self.grid.add(self.canvas)
        self.grid.attach_next_to(self.SideBox, self.canvas, Gtk.PositionType.RIGHT, 1, 1)
        self.grid.attach_next_to(self.progress, self.canvas, Gtk.PositionType.BOTTOM, 1, 1)
        self.grid.attach_next_to(self.status, self.SideBox, Gtk.PositionType.BOTTOM, 1, 1)

        self.window.show_all()

        self.spectrum = Spectrum(self.stage, self.settings, self.status, self.progress, self.enable_buttons,
                                 self.disable_buttons)  # logger class which coordinates the spectrometer and the stage

        spec = self.spectrum.get_spec()  # get an initial spectrum for display
        self._wl = self.spectrum.get_wl()  # get the wavelengths
        print(self._wl)
        self.lines = []
        self.lines.extend(self.ax.plot(self._wl, spec, "-"))
        self.lines.extend(self.ax.plot(self._wl, self.spectrum.smooth(spec), "-", c="black"))  # plot initial spectrum

        #Dialogs
        self.settings_dialog = dialogs.SettingsDialog(self.window, self.settings)
        self.direction_dialog = dialogs.DirectionDialog(self.window, self.settings)
        self.moveabs_dialog = dialogs.MoveAbsDialog(self.window, self.stage)
        self.moverel_dialog = dialogs.MoveRelDialog(self.window, self.stage)
        self.spangrid_dialog = dialogs.SpanGridDialog(self.window)
        self.prefix_dialog = dialogs.PrefixDialog(self.window)

        self.pad = None
        try:
            #pass
            self.pad = Gamepad(True)
        except:
            print("Could not initialize Gamepad")



    def quit(self, *args):
        """
        Function for quitting the program, will also stop the worker thread
        :param args:
        """
        self.spectrum = None
        self.pad = None
        Gtk.main_quit(*args)

    def disable_buttons(self):
        # self.stack_switcher.set_sensitive(False)
        self.scan_hbox.set_sensitive(False)
        self.SpectrumBox.set_sensitive(False)
        self.stage_hbox.set_sensitive(False)
        self.ScanningBox.set_sensitive(False)
        self.button_stop.set_sensitive(True)


    def enable_buttons(self):
        # self.stack_switcher.set_sensitive(True)
        self.scan_hbox.set_sensitive(True)
        self.SpectrumBox.set_sensitive(True)
        self.stage_hbox.set_sensitive(True)
        self.ScanningBox.set_sensitive(True)
        self.button_stop.set_sensitive(False)

    def _on_pad_change(self, io, condition):
        a, b, x, y, ax, ay = self.pad.receiver.recv()
        if a:
            self.on_stepdown_clicked(None)
        if b:
            self.on_add_position_clicked(None)
        if x:
            self.on_search_clicked(None)
        if y:
            self.on_stepup_clicked(None)

        self.x_step = float((ax - 128))
        if abs(self.x_step) > 8:
            self.x_step = self.x_step / 128 * self.settings.stepsize
        else:
            self.x_step = 0.0

        self.y_step = float((ay - 128))
        if abs(self.y_step) > 8:
            self.y_step = self.y_step / 128 * self.settings.stepsize
        else:
            self.y_step = 0.0
        # print('x_step: {0:3.2f} um   y_step: {1:3.2f} um'.format( self.x_step, self.y_step))
        return True

    def _pad_make_step(self):
        if self.pad is not None:
            if abs(self.x_step) > 0.0001:
                if abs(self.y_step) > 0.0001:
                    self.stage.moverel(dx=self.x_step, dy=self.y_step)
                else:
                    self.stage.moverel(dx=self.x_step)
            elif abs(self.y_step) > 0.001:
                self.stage.moverel(dy=self.y_step)
        return True

    # ##---------------- button connect functions ----------

    def on_scan_start_clicked(self, widget):
        prefix = self.prefix_dialog.rundialog()

        if prefix is not None:
            try:
                # os.path.exists(prefix)
                os.mkdir(self.savedir+prefix)
            except:
                print("Error creating directory ./" + prefix)
            path = self.savedir + prefix + '/'
            self.status.set_label('Scanning')
            self.spectrum.make_scan(self.scan_store, path, self.button_searchonoff.get_active(),
                                    self.button_lockinonoff.get_active())
            self.disable_buttons()


    def on_add_position_clicked(self, widget):
        self.stage.query_pos()
        pos = self.stage.last_pos()
        self.scan_store.append([pos[0], pos[1]])

    def on_spangrid_clicked(self, widget):
        iterator = self.scan_store.get_iter_first()
        grid = self.spangrid_dialog.rundialog()
        if (len(self.scan_store) >= 3) & ((grid[0] is not 0) | (grid[1] is not 0)):
            a = self.scan_store[iterator][:]
            iterator = self.scan_store.iter_next(iterator)
            b = self.scan_store[iterator][:]
            iterator = self.scan_store.iter_next(iterator)
            c = self.scan_store[iterator][:]

            if abs(b[0]) > abs(c[0]):
                grid_vec_1 = [b[0] - a[0], b[1] - a[1]]
                grid_vec_2 = [c[0] - a[0], c[1] - a[1]]
            else:
                grid_vec_2 = [b[0] - a[0], b[1] - a[1]]
                grid_vec_1 = [c[0] - a[0], c[1] - a[1]]

            self.scan_store.clear()

            for x in range(int(grid[0])):
                for y in range(int(grid[1])):
                    vec_x = a[0] + grid_vec_1[0] * x + grid_vec_2[0] * y
                    vec_y = a[1] + grid_vec_1[1] * x + grid_vec_2[1] * y
                    self.scan_store.append([vec_x, vec_y])


    def on_stop_clicked(self, widget):
        self.spectrum.stop_process()
        self.enable_buttons()
        self.status.set_label('Stopped')

    def on_reset_clicked(self, widget):
        self.spectrum.reset()
        self.spectrum.dark = None
        self.spectrum.lamp = None
        self.spectrum.lockin = None
        self.spectrum.mean = None

    def on_lockin_clicked(self, widget):
        self.status.set_label('Acquiring ...')
        self.spectrum.take_lockin()
        self.disable_buttons()

    def on_direction_clicked(self, widget):
        self.direction_dialog.rundialog()

    def on_live_clicked(self, widget):
        self.status.set_label('Liveview')
        self.spectrum.take_live()
        self.disable_buttons()

    def on_search_clicked(self, widget):
        self.status.set_text("Searching Max.")
        self.spectrum.search_max()
        self.disable_buttons()

    def on_save_clicked(self, widget):
        self.status.set_label("Saving Data ...")
        self.save_data()

    def on_settings_clicked(self, widget):
        self.settings_dialog.rundialog()
        self.ax.set_xlim([self.settings.min_wl, self.settings.max_wl])
        #self.spectrum.reset()

    def on_dark_clicked(self, widget):
        self.status.set_label('Taking Dark Spectrum')
        self.spectrum.take_dark()
        self.disable_buttons()

    def on_lamp_clicked(self, widget):
        self.status.set_label('Taking Lamp Spectrum')
        self.spectrum.take_lamp()
        self.disable_buttons()

    def on_normal_clicked(self, widget):
        self.status.set_label('Taking Normal Spectrum')
        self.spectrum.take_normal()
        self.disable_buttons()

    def on_bg_clicked(self, widget):
        self.status.set_label('Taking Background Spectrum')
        self.spectrum.take_bg()
        self.disable_buttons()

    def on_series_clicked(self, widget):
        self.status.set_label('Taking Time Series')
        prefix = self.prefix_dialog.rundialog()
        if prefix is not None:
            try:
                # os.path.exists(prefix)
                os.mkdir(self.savedir+prefix)
            except:
                print("Error creating directory ./" + prefix)
            path = self.savedir + prefix + '/'
        else:
            self.status.set_text("Error")
        self.spectrum.take_series(path)
        self.disable_buttons()


    def on_loaddark_clicked(self, widget):
        buf = self._load_spectrum_from_file()
        if not buf is None:
            self.spectrum.dark = buf

    def on_loadlamp_clicked(self, widget):
        buf = self._load_spectrum_from_file()
        if not buf is None:
            self.spectrum.lamp = buf

    # ##---------------- END button connect functions ----------

    def _load_spectrum_from_file(self):
        dialog = Gtk.FileChooserDialog("Please choose a file", self.window,
                                       Gtk.FileChooserAction.OPEN,
                                       (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                                        Gtk.STOCK_OPEN, Gtk.ResponseType.OK))

        data = None
        filter_text = Gtk.FileFilter()
        filter_text.set_name("CSV Spectrum files")
        filter_text.add_pattern("*.csv")
        dialog.add_filter(filter_text)
        dialog.set_current_folder(os.path.dirname(os.path.abspath(__file__)))
        response = dialog.run()
        if response == Gtk.ResponseType.OK:
            data = pandas.DataFrame(pandas.read_csv(dialog.get_filename()))
            data = data['intensity']
        elif response == Gtk.ResponseType.CANCEL:
            data = None
        dialog.destroy()
        return data

    # ## ----------- scan Listview connect functions

    def on_scan_xedited(self, widget, path, number):
        self.scan_store[path][0] = float(number.replace(',', '.'))
        # self.plotpoints()

    def on_scan_yedited(self, widget, path, number):
        self.scan_store[path][1] = float(number.replace(',', '.'))
        # self.plotpoints()

    def on_scan_add(self, widget):
        self.scan_store.append()

    def on_scan_remove(self, widget):
        select = self.scan_view.get_selection()
        model, treeiter = select.get_selected()
        if treeiter is not None:
            self.scan_store.remove(treeiter)

    def on_scan_clear(self, widget):
        self.scan_store.clear()


    # ## ----------- END scan Listview connect functions


    # ##---------------- Stage Control Button Connect functions ----------

    def show_pos(self):
        pos = self.stage.last_pos()
        # print(pos)
        self.label_x.set_text("x: {0:+8.4f}".format(pos[0]))
        self.label_y.set_text("y: {0:+8.4f}".format(pos[1]))
        self.label_z.set_text("z: {0:+8.4f}".format(pos[2]))

    def on_xup_clicked(self, widget):
        self.stage.moverel(dx=self.settings.stepsize)
        self.show_pos()

    def on_xdown_clicked(self, widget):
        self.stage.moverel(dx=-self.settings.stepsize)
        self.show_pos()

    def on_yup_clicked(self, widget):
        self.stage.moverel(dy=self.settings.stepsize)
        self.show_pos()

    def on_ydown_clicked(self, widget):
        self.stage.moverel(dy=-self.settings.stepsize)
        self.show_pos()

    def on_zup_clicked(self, widget):
        self.stage.moverel(dz=self.settings.stepsize)
        self.show_pos()

    def on_zdown_clicked(self, widget):
        self.stage.moverel(dz=-self.settings.stepsize)
        self.show_pos()

    def on_stepup_clicked(self, widget):
        self.settings.stepsize *= 10
        if self.settings.stepsize > 10:
            self.settings.stepsize = 10.0
        self.label_stepsize.set_text(str(self.settings.stepsize))
        self.settings.save()

    def on_stepdown_clicked(self, widget):
        self.settings.stepsize /= 10
        if self.settings.stepsize < 0.001:
            self.settings.stepsize = 0.001
        self.label_stepsize.set_text(str(self.settings.stepsize))
        self.settings.save()

    def on_moverel_clicked(self, widget):
        self.moverel_dialog.rundialog()
        self.show_pos()

    def on_moveabs_clicked(self, widget):
        self.moveabs_dialog.rundialog()
        self.show_pos()


    # ##---------------- END Stage Control Button Connect functions ------

    def run(self):
        """	run main gtk thread """
        try:
            GLib.timeout_add(self._heartbeat, self._update_plot)
            GLib.timeout_add(self._heartbeat, self._pad_make_step)
            GLib.io_add_watch(self.spectrum.conn_for_main, GLib.IO_IN | GLib.IO_PRI, self.spectrum.callback,
                              args=(self.spectrum,))
            if self.pad is not None:
                GLib.io_add_watch(self.pad.receiver, GLib.IO_IN | GLib.IO_PRI, self._on_pad_change, args=(self,))
            Gtk.main()
        except KeyboardInterrupt:
            pass

    def _update_plot(self):
        spec = self.spectrum.get_spec(self.button_corronoff.get_active())
        self.lines[0].set_ydata(spec)
        self.lines[1].set_ydata(self.spectrum.smooth(spec))
        #self.ax.set_ylim(min(spec[262:921]), max(spec[262:921]))
        self.ax.autoscale_view(None, False, True)
        self.canvas.draw()
        self.show_pos()
        return True

    def save_data(self):
        prefix = self.prefix_dialog.rundialog()
        if prefix is not None:
            try:
                # os.path.exists(prefix)
                os.mkdir(self.savedir+prefix)
            except:
                print("Error creating directory ./" + prefix)
            path = self.savedir + prefix + '/'
            self.spectrum.save_data(path)
            self.status.set_text("Data saved")
        else:
            self.status.set_text("Could not save data")
示例#12
0
class Editor(gtk.Dialog):
    X = 0
    Y = 1

    def get_globals(self):
        if self.globals_src:
            return self.globals_src()
        return self.globals

    def __init__(self,
                 channels,
                 title='Edit Scaling',
                 parent=None,
                 target=None,
                 model=False,
                 add_undo=None,
                 globals_src=None,
                 globals=globals()):
        self.add_undo = add_undo
        self.channels = channels
        self.globals_src = None
        if globals_src:
            assert callable(globals_src), 'expected callable globals_src'
            self.globals_src = globals_src
        self.globals = globals

        self.handlers = dict()
        self.chan = None

        flags = gtk.DialogFlags.DESTROY_WITH_PARENT
        if model:
            flags |= gtk.DialogFlags.MODAL

        super(Editor, self).__init__(title, parent, flags)

        self.set_default_size(550, 600)
        self.set_border_width(10)

        self.pause_update = False

        V = self.view = gtk.TreeView()
        V.set_property('rules-hint', True)
        V.get_selection().set_mode(gtk.SelectionMode.MULTIPLE)

        self.sheet_cb = spreadsheet.Callbacks(V, ('', ''))
        self.sheet_cb.connect('clean', lambda: self.set_pause(True),
                              lambda: self.set_pause(False))

        self.renderers = R = {
            'x': GCRT(),
            'y': GCRT(),
        }

        R['x'].set_property('editable', True)
        R['y'].set_property('editable', True)

        C = {
            'x': GTVC('Voltage (V)', R['x'], text=Editor.X),
            'y': GTVC('Output (V)', R['y'], text=Editor.Y),
        }

        V.append_column(C['x'])
        V.append_column(C['y'])
        self.C = C

        V.set_size_request(200, 100)

        # create the scrolled window for the spreadsheet
        sw = gtk.ScrolledWindow()
        sw.set_policy(gtk.PolicyType.AUTOMATIC, gtk.PolicyType.AUTOMATIC)
        sw.set_shadow_type(gtk.ShadowType.IN)
        sw.add(V)

        # Create the plotting canvas
        f = Figure(figsize=(5, 4), dpi=100)
        self.axes = f.add_subplot(111)
        self.canvas = FigureCanvas(f)  # a gtk.DrawingArea
        self.canvas.set_size_request(300, 100)
        toolbar = NavigationToolbar(self.canvas, self)
        self.plot_offset_label = gtk.Label('Plot Offset [V]:')

        self.channel_select = gtk.ComboBox.new_with_model(channels)
        cbr = gtk.CellRendererText()
        self.channel_select.clear()
        self.channel_select.pack_start(cbr, True)
        self.channel_select.add_attribute(cbr, 'text', channels.LABEL)
        self.channel_select.connect(
            'changed',
            lambda c: self._set_channel(self.channels[c.get_active()]))

        # This ensures you can't select digital channels
        def is_sensitive(celllayout, cell, model, i, *user_args):
            if model[i][model.DEVICE].lower().startswith('digital/'):
                cell.set_property('sensitive', False)
                cell.set_property('visible', False)
            else:
                cell.set_property('sensitive', True)
                cell.set_property('visible', True)

        self.channel_select.set_cell_data_func(cbr, is_sensitive)

        self.units = gtk.Entry()
        self.units.set_width_chars(8)

        def update_units_label(entry):
            T = self.units.get_text()
            # just a simple test to see if the units evaluate
            eval(T, self.get_globals())

            C['y'].set_title('Output ({})'.format(T))
            self.axes.set_ylabel('Output ({})'.format(T))
            self.canvas.draw()
            if self.chan and self.chan[self.channels.UNITS] != T:
                self.chan[self.channels.UNITS] = T
                self.update_plot()

        self.units.connect('activate', update_units_label)
        self.units.set_text('V')

        self.offset = gtk.Entry()
        self.offset.set_width_chars(10)

        def update_offset(entry):
            T = self.offset.get_text()
            # just a simple test to see if the units evaluate
            if not T:
                T = None
            elif T.partition('#')[0].strip():
                eval(T, self.get_globals())

            if self.chan and self.chan[self.channels.OFFSET] != T:
                self.chan[self.channels.OFFSET] = T
                self.update_plot()

        self.offset.connect('activate', update_offset)

        self.order = gtk.SpinButton()
        self.order.set_range(1, 5)
        self.order.set_increments(1, 2)

        def update_order(entry):
            if self.chan:
                self.chan[self.channels.
                          INTERP_ORDER] = self.order.get_value_as_int()
                self.update_plot()

        self.order.connect('value-changed', update_order)
        self.order.set_value(1)

        self.smoothing = gtk.SpinButton(digits=3)
        self.smoothing.set_range(0, 10000000)
        self.smoothing.set_increments(0.5, 1)

        def update_smoothing(entry):
            if self.chan:
                self.chan[self.channels.
                          INTERP_SMOOTHING] = self.smoothing.get_value()
                self.update_plot()

        self.smoothing.connect('value-changed', update_smoothing)
        self.smoothing.set_value(0)


        self.enforce_scale_offset = \
          NumberEntryEnforcer(self, self.channels.PLOT_SCALE_OFFSET, True)
        self.scale_offset = gtk.Entry()
        self.scale_offset.set_text('0.0')
        self.scale_offset.set_width_chars(15)
        self.scale_offset.connect('changed', self.enforce_scale_offset)
        self.scale_offset.connect('activate',
                                  self.enforce_scale_offset.activate)
        self.scale_offset.set_tooltip_text(
            'Specify an offset for the waveform plot')

        self.enforce_scale_factor = \
          NumberEntryEnforcer(self, self.channels.PLOT_SCALE_FACTOR, True)
        self.scale_factor = gtk.Entry()
        self.scale_factor.set_text('1.0')
        self.scale_factor.set_width_chars(15)
        self.scale_factor.connect('changed', self.enforce_scale_factor)
        self.scale_factor.connect('activate',
                                  self.enforce_scale_factor.activate)
        self.scale_factor.set_tooltip_text(
            'Specify a scaling factor for the waveform plot')

        ubox = gtk.HBox()
        ubox.pack_start(self.channel_select, True, True, 0)
        ubox.pack_start(gtk.Label('Output Scale/Units:  '), True, True, 0)
        ubox.pack_start(self.units, True, True, 0)

        pbox = gtk.HBox()
        pbox.pack_start(gtk.Label('Interpolation:      Order:'), True, True, 0)
        pbox.pack_start(self.order, True, True, 0)
        pbox.pack_start(gtk.Label('Smoothing:'), True, True, 0)
        pbox.pack_start(self.smoothing, True, True, 0)

        obox = gtk.HBox()
        obox.pack_start(gtk.Label('Output Offset/Units:'), True, True, 0)
        obox.pack_start(self.offset, True, True, 0)

        sbox = gtk.HBox()
        sbox.pack_start(self.plot_offset_label, True, True, 0)
        sbox.pack_start(self.scale_offset, True, True, 0)
        sbox.pack_start(gtk.Label('Plot Scale:'), True, True, 0)
        sbox.pack_start(self.scale_factor, True, True, 0)

        bottom = gtk.VBox()
        bottom.pack_start(ubox, False, False, 0)
        bottom.pack_start(pbox, False, False, 0)
        bottom.pack_start(obox, False, False, 0)
        bottom.pack_start(sbox, False, False, 0)
        bottom.pack_start(sw, True, True, 0)

        body = gtk.VPaned()
        body.pack1(self.canvas, True)
        body.pack2(bottom, True)
        self.vbox.pack_start(toolbar, False, False, 0)
        self.vbox.pack_start(body, True, True, 0)
        self.show_all()

        # default to first channel
        self.set_channel()

    def set_channel(self, label=None):
        """Determines the new channel and sets it"""
        if not (self.channels and len(self.channels)):
            return

        if label == None:
            return
        if label != self.channels[self.channel_select.get_active()]:
            for i in range(len(self.channels)):
                if label == self.channels[i][self.channels.LABEL]:
                    self.channel_select.set_active(i)
                    # we rely on the channel_select callback to finish this
                    return
            raise KeyError('Could not determine channel')

    def _set_channel(self, chan):
        #disconnect handlers from old model
        if self.chan:
            for i in self.handlers['store']:
                self.chan[self.channels.SCALING].disconnect(i)

            for i in self.handlers['x']:
                self.renderers['x'].disconnect(i)

            for i in self.handlers['y']:
                self.renderers['y'].disconnect(i)

        if not (self.channels and len(self.channels)):
            return

        self.set_pause(True)

        self.chan = None
        self.view.set_model(None)

        # set new model
        if chan[self.channels.SCALING] is None:
            chan[self.channels.SCALING] = gtk.ListStore(str, str)
        if not chan[self.channels.UNITS]:
            chan[self.channels.UNITS] = 'V'
        if chan[self.channels.INTERP_ORDER] < 1:
            chan[self.channels.INTERP_ORDER] = 1

        devname = chan[self.channels.DEVICE].lower()
        if devname.startswith('analog/'):
            self.C['x'].set_title('Voltage (V)')
            self.plot_offset_label.set_text('Plot Offset [V]:')
        elif devname.startswith('dds/'):
            self.C['x'].set_title('Frequency (Hz)')
            self.plot_offset_label.set_text('Plot Offset [Hz]:')
        # INTERP_SMOOTHING defaults to zero already

        self.units.set_text(chan[self.channels.UNITS])
        self.units.activate()
        self.offset.set_text(chan[self.channels.OFFSET] or '')
        self.order.set_value(chan[self.channels.INTERP_ORDER])
        self.smoothing.set_value(chan[self.channels.INTERP_SMOOTHING])
        self.scale_offset.set_text(fstr(chan[self.channels.PLOT_SCALE_OFFSET]))
        self.scale_factor.set_text(
            fstr(chan[self.channels.PLOT_SCALE_FACTOR], '1.0'))
        store = chan[self.channels.SCALING]
        self.view.set_model(store)

        #connect handlers to new model
        self.handlers['store'] = [
            store.connect('row-changed', lambda m, p, i: self.update_plot()),
            store.connect('row-deleted', lambda m, p: self.update_plot()),
            store.connect('row-inserted', lambda m, p, i: self.update_plot()),
        ]

        self.handlers['x'] = self.sheet_cb.connect_column(
            self.renderers['x'],
            setitem=(set_item, store, Editor.X, self.add_undo, True))

        self.handlers['y'] = self.sheet_cb.connect_column(
            self.renderers['y'],
            setitem=(set_item, store, Editor.Y, self.add_undo))

        self.chan = chan
        self.set_pause(False)
        # clear the plot entirely first to avoid keeping a plot with no data-table
        self.axes.clear()
        self.canvas.draw()
        self.update_plot()

    def plot(self, *args, **kwargs):
        """Send the data to matplotlib"""
        self.axes.clear()
        self.axes.plot(*args, **kwargs)
        pylab.setp(self.axes.get_xticklabels(), fontsize=8)
        pylab.setp(self.axes.get_yticklabels(), fontsize=8)
        self.axes.grid(True)
        self.axes.set_xlabel('Voltage (V)')
        self.axes.set_ylabel('Output ({})'.format(self.units.get_text()))
        self.canvas.draw()

    def set_pause(self, arg):
        """Do not send to plotter just because a signal handler was called"""
        self.pause_update = bool(arg)

    def update_plot(self):
        if self.pause_update:
            return

        D = calculate(self.chan[self.channels.SCALING],
                      self.chan[self.channels.UNITS],
                      self.chan[self.channels.OFFSET], self.get_globals())

        if len(D):
            if len(D) > 1:
                s = UnivariateSpline(
                    D[:, 0],
                    D[:, 1],
                    k=self.order.get_value_as_int(),
                    s=self.smoothing.get_value(),
                )
                xs = np.linspace(D[0, 0], D[-1, 0], 100 * len(D))
                self.plot(D[:, 0], D[:, 1], 'o', xs, s(xs))
            else:
                self.plot(D[:, 0], D[:, 1], 'o')
示例#13
0
class MyWindow(Gtk.Window):
    def __init__(self):
        """View initializer."""
        super().__init__()

        self.set_title("Kości")
        self.set_default_size(500, 800)

        self.generalLayout = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
        self.add(self.generalLayout)
        self.left = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.right = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)

        self._createMenu()
        self.generalLayout.add(self.left)
        self.generalLayout.add(self.right)
        self._createPlot()
        self._createDisplay()
        self._createList()
        self._createLabels()
        self._createButtons()
        self._createRadio()

        self.connect("destroy", Gtk.main_quit)
        self.show_all()

    def _createPlot(self):
        self.fig = plt.Figure(figsize=(5, 4), dpi=100)
        self.ax = self.fig.add_subplot()

        self.canvas = FigureCanvas(self.fig)  # a Gtk.DrawingArea
        self.canvas.set_size_request(800, 600)
        self.left.add(self.canvas)
        #ax.plot(t, s)

    def _createDisplay(self):
        """Create the display."""

        self.display = Gtk.Label("")

        #self.display.setFixedeight(50)
        #self.display.setAlignment(Qt.AlignLeft)
        #self.display.setReadOnly(True)

        self.left.add(self.display)

    def _createLabels(self):
        """Create the buttons."""
        self.labels = {}
        self.names = {}
        labelsLayout = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)

        labels = {
            "liczba ścian": (0, 0),
            "kości": (0, 1),
            "próg sukcesu": (0, 2),
            "wymagana liczba sukcesów": (0, 3),
            "modyfikator": (0, 4),
        }

        for lblText, pos in labels.items():
            self.labels[lblText] = Gtk.Entry()
            self.labels[lblText].set_text(lblText)

            self.names[lblText] = Gtk.Label(lblText + ":")
            #self.labels[lblText].setValidator(QIntValidator())

            #self.labels[lblText].setFixedSize(40, 40)
            labelsLayout.add(self.names[lblText])
            labelsLayout.add(self.labels[lblText])

            if lblText == "wymagana liczba sukcesów":
                self.check = Gtk.CheckButton()
                labelsLayout.add(self.check)

        self.right.add(labelsLayout)

    def _createButtons(self):
        """Create the buttons."""
        self.buttons = {}
        buttonsLayout = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)

        buttons = {
            "oblicz": (0, 0),
            "rzuć": (0, 1),
            "dodaj element łańcucha": (0, 2),
        }

        for btnText, pos in buttons.items():
            self.buttons[btnText] = Gtk.Button(label=btnText)
            #self.buttons[btnText].setFixedSize(15, 40)
            buttonsLayout.add(self.buttons[btnText])

        self.right.add(buttonsLayout)

    def _createList(self):
        self.cb = Gtk.ComboBoxText()
        self.cb.append_text("Krok 1")
        self.right.add(self.cb)

    def _createMenu(self):

        mb = Gtk.MenuBar()

        menu1 = Gtk.Menu()

        file = Gtk.MenuItem("Menu")
        file.set_submenu(menu1)
        acgroup = Gtk.AccelGroup()
        self.add_accel_group(acgroup)

        self.info = Gtk.MenuItem("Informacje")
        self.clear = Gtk.MenuItem("Wyczyść")

        menu1.append(self.info)
        menu1.append(self.clear)
        self.info.connect("activate", self.information)

        mb.append(file)
        vbox = Gtk.VBox(False, 2)
        vbox.pack_start(mb, False, False, 0)

        self.generalLayout.add(vbox)

    def _createRadio(self):

        self.radios = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.rb = []

        self.rb.append(Gtk.RadioButton(label="Brak przerzutu"))
        self.rb.append(Gtk.RadioButton(label="Przerzut jedynek"))
        self.rb.append(Gtk.RadioButton(label="Przerzut nieudanych"))
        self.rb.append(Gtk.RadioButton(label="Przerzut x kości"))

        self.x_name = Gtk.Label("x: ")

        self.x_input = Gtk.Entry()
        self.x_input.set_text(str(0))

        self.radios.pack_start(self.rb[0], True, True, 0)
        self.radios.pack_start(self.rb[1], True, True, 0)
        self.radios.pack_start(self.rb[2], True, True, 0)
        self.radios.pack_start(self.rb[3], True, True, 0)
        self.radios.add(self.x_name)
        self.radios.add(self.x_input)

        self.rb[1].join_group(self.rb[0])
        self.rb[2].join_group(self.rb[0])
        self.rb[3].join_group(self.rb[0])

        self.right.add(self.radios)

    def setDisplayText(self, text):
        """Set display's text."""
        self.display.set_text(text)

    def displayText(self):
        """Get display's text."""
        return self.display.text()

    def clearDisplay(self):
        """Clear the display."""
        self.setDisplayText("")

    def information(self, source):
        msg = Gtk.MessageDialog(
            parent=self,
            flags=Gtk.DialogFlags.MODAL,
            type=Gtk.MessageType.INFO,
            buttons=Gtk.ButtonsType.OK,
            message_format=
            "Aplikacja ma być ułatwieniem dla osób grających w gry planszowe, rpg i bitewne. Jej zadaniem jest obliczanie prawdopodobieństw uzyskania wskazanych wyników rzutów kośćmi oraz dokonywanie symulacji takich rzutów"
        )

        msg.run()
        msg.destroy()

    def plot(self, source, roller):
        self.ax.cla()
        data = roller.calculate()
        x = list(range(len(data)))
        self.ax.bar(x, data)

        self.canvas.draw()

    def showRollResult(self, button, roller):
        result = roller.roll()
        success = ""
        if result[2]:
            success = " Rzut udany!"
        else:
            success = " Rzut nieudany"
        self.setDisplayText("Wyniki rzutu:" + str(result[0]) + " Sukcesy:" +
                            str(result[1]) + success)

    def addStep(self, source, chain):
        roller = dice.rolling_step()
        chain.add_step(roller)
        self.cb.append_text("Krok " + str(chain.num_of_steps()))

    def changeStep(self, source, chain):
        index = self.cb.get_active()
        self.labels["liczba ścian"].set_text(str(chain.steps[index].sides))
        self.labels["kości"].set_text(str(chain.steps[index].amount_of_dice))
        self.labels["próg sukcesu"].set_text(str(chain.steps[index].success))
        self.labels["wymagana liczba sukcesów"].set_text(
            str(chain.steps[index].needed_successes))
        self.labels["modyfikator"].set_text(str(chain.steps[index].modifier))

        self.x_input.set_text(str((chain.steps[index].dice_for_reroll)))

        self.check.set_active(chain.steps[index].success_required)

        self.rb[int(chain.steps[index].rerolls)].set_active(True)

    def updateDice(self, source, event, chain):
        numOnly(source)
        chain.steps[self.cb.get_active()].amount_of_dice = int(
            self.labels["kości"].get_text())

    def updateSides(self, source, event, chain):
        numOnly(source)
        chain.steps[self.cb.get_active()].sides = int(
            self.labels["liczba ścian"].get_text())

    def updateSuccess(self, source, event, chain):
        numOnly(source)
        chain.steps[self.cb.get_active()].success = int(
            self.labels["próg sukcesu"].get_text())

    def updateNeededSuccesses(self, source, event, chain):
        numOnly(source)
        chain.steps[self.cb.get_active()].needed_successes = int(
            self.labels["wymagana liczba sukcesów"].get_text())

    def updateModifier(self, source, event, chain):
        numOnly(source)
        chain.steps[self.cb.get_active()].modifier = int(
            self.labels["modyfikator"].get_text())

    def updateDiceToReroll(self, source, event, chain):
        numOnly(source)
        chain.steps[self.cb.get_active()].dice_for_reroll = int(
            self.x_input.get_text())

    def updateRerolls(self, source, chain):
        if self.rb[0].get_active():
            chain.steps[self.cb.get_active()].rerolls = dice.Rerolls.none
        if self.rb[1].get_active():
            chain.steps[self.cb.get_active()].rerolls = dice.Rerolls.ones
        if self.rb[2].get_active():
            chain.steps[self.cb.get_active()].rerolls = dice.Rerolls.all
        if self.rb[3].get_active():
            chain.steps[self.cb.get_active()].rerolls = dice.Rerolls.dice

    def updateSuccessRequired(self, source, chain):
        chain.steps[self.cb.get_active()].success_required = not chain.steps[
            self.cb.get_active()].success_required

    def clearChain(self, source, chain):
        chain.steps = []
        chain.steps.append(dice.rolling_step())
        self.cb.remove_all()
        self.cb.append_text("Krok 1")
        self.cb.set_active(0)
示例#14
0
class ChessAnalogWindow(Gtk.Window):
    def __init__(self):
        Gtk.Window.__init__(self, title="CHESS Analog")
        self.set_default_size(800, 600)

        self.dev = None
        # number of plot points to plot at any one time.
        self.fifo_size = 1000
        # Buffer for plot data
        self.analog_data = []
        #self.analog_data = [32*collections.deque(self.fifo_size*[0], self.fifo_size)]
        # Init plot data container
        for i in range(NUM_CHANNELS):
            self.analog_data.append(collections.deque(self.fifo_size*[0], self.fifo_size))
        self.x = collections.deque(self.fifo_size*[0], self.fifo_size)
        # Buffer for reading from file device.
        self.data_buf = ""

        self.connect("destroy", self.on_destroy)

        # Initialize the DAQ card
        if (self.pci_6033e_init(DEVICE) < 0):
            warn_dialog("Could not initialize comedi device -- closing")
            # Quit if we can't get the daq...
            Gtk.main_quit()
        
        print("Comedi device successfully initialized \n\n")

        self.master_vbox = Gtk.Box(spacing = 2, orientation = 'vertical')
        self.master_hbox = Gtk.Box(spacing = 2)

        #self.master_vbox.pack_start(self.master_hbox, True, True, 0)
        self.add(self.master_vbox)

        self.action_acq = Gtk.ToggleAction("Acquire", "Acquire", "Get the datas", None)
        self.action_acq.connect("toggled", self.acquire_cb)

        toolbar_action_group = Gtk.ActionGroup("toolbar_actions")
        toolbar_action_group.add_action(self.action_acq)

        # UI Stuff
        uimanager = Gtk.UIManager()

        # Throws exception if something went wrong
        uimanager.add_ui_from_string(UI_INFO)
        uimanager.insert_action_group(toolbar_action_group)
        
        toolbar = uimanager.get_widget("/ToolBar")
        self.master_vbox.pack_start(toolbar, False, False, 0)


        self.liststore = Gtk.ListStore(str, float)
        for i in range(32):
            self.liststore.append([str(i), 0])

        self.treeview = Gtk.TreeView(model=self.liststore)
        
        chan_text = Gtk.CellRendererText()
        column_text = Gtk.TreeViewColumn("Channel", chan_text, text=0)
        self.treeview.append_column(column_text)

        meas_text = Gtk.CellRendererText()
        mcolumn_text = Gtk.TreeViewColumn("Measurement", meas_text, text=1)
        self.treeview.append_column(mcolumn_text)

        self.master_vbox.pack_start(self.master_hbox, True, True, 0)
        #self.add(treeview)
        self.master_hbox.pack_start(self.treeview, False, False, 0)

        #self.liststore[31][1] = 18000
        #GObject.timeout_add(200, self.my_timer)
        self.timer_id = None
        self.plot_id = None

        self.f = Figure(figsize=(8,6), dpi=100)
        self.a = self.f.add_subplot(111)
        
        #self.line, = self.a.plot([], [], marker = 'x')
        #self.line, = self.a.plot([], [])
        #self.plt = self.a.plot([0, 1], [0, 3], marker = 'x')
        self.a.xaxis.set_animated(True)
        self.a.yaxis.set_animated(True)

        #self.a.set_xlim([0,5])
        self.a.set_xlim([self.fifo_size/SCAN_FREQ, 0])
        
        self.a.set_ylim([0,70000])
        
        self.a.grid(True)
        #self.a.set_xscale('log')
        #self.a.set_xlim((10.0, 30000.0))
        #self.a.set_ylim((-90.0, 3.0))
        self.a.set_xlabel("Time")
        self.a.set_ylabel("Voltage")

        self.lastx = 0
        self.my_line, = self.a.plot([], [], animated = True)
        self.my_line2, = self.a.plot([], [], animated = True)
        
        self.canvas = FigureCanvas(self.f)

        # Clean background
        self.clean_bg = self.canvas.copy_from_bbox(self.f.bbox)
        self.background = self.canvas.copy_from_bbox(self.get_bg_bbox(self.a))

        self.old_size = self.a.bbox.width, self.a.bbox.height

        self.canvas.draw()

        self.do_redraw = False

        #self.plot_timer = self.canvas.new_timer(interval = 42)

        # self.anim = ma.FuncAnimation(self.f, 
        #                              self.update_plots, 
        #                              event_source = self.plot_timer, 
        #                              init_func = self.init_blit_plot, 
        #                              repeat = False,
        #                              blit = True)

        #print(dir(self.anim))
        #self.anim._stop()
        #self.plot_timer.stop()
        self.master_hbox.pack_start(self.canvas, True, True, 0)
        #self.plot_timer.stop()

        self.connect("check-resize", self.win_resize)

    def acquire_cb(self, state):
        #print("acq callback")
        #print(state)
        if (self.action_acq.get_active()):
            # This is commented because it seems that comedi_cancel()
            # clears stale data in the fd and card?
            #data = os.read(self.fd, BUF_SIZE)
            #print("LEN DATA: %d" % len(data))

            # Start comedi command
            ret = c.comedi_command(self.dev, self.cmd)
            if (ret != 0):
                self.warn_dialog("PCI-6033E cannot collect data! Error: %d" % ret)
                print(c.comedi_strerror(c.comedi_errno()))
                return(False)



            #self.timer_id = GObject.timeout_add(100, self.my_timer)
            # Make these timeouts configurable...
            self.plotter_id = GObject.timeout_add(250, self.update_plots)
            self.plot_id = GObject.timeout_add(500, self.num_data_timer)
            self.timer_id = GObject.timeout_add(20, self.pci_6033e_get_data)
            #self.plot_timer.start()
            self.action_acq.set_label("Halt")
        else:
            self.action_acq.set_label("Acquire")
            if (self.timer_id):
                if (c.comedi_cancel(self.dev, SUBDEVICE) < 0):
                    print("failed to cancel comedi command...")
                GObject.source_remove(self.timer_id)
            if (self.plot_id):
                GObject.source_remove(self.plot_id)
            if (self.plotter_id):
                GObject.source_remove(self.plotter_id)
            #self.plot_timer.stop()
            # Empty stale data
            self.data_buf = ""
            # print(self.x)
            # print(self.analog_data[0])

    # Get the bounding box
    def get_bg_bbox(self, axe):
        # just pad x0 by three....
        return axe.bbox.padded(-3)

    def num_data_timer(self):
        # Print numerical data to treeview
        for i in range(32):
            #     datal.append(c.comedi_to_phys(j, crange, maxdata))
            self.liststore[i][1] = c.comedi_to_phys(self.analog_data[i][-1], 
                                                    self.comedi_range, 
                                                    (self.comedi_maxdata + 1))
            
        return(True)

    def pci_6033e_get_data(self):
        # Run the command
        # ret = c.comedi_command(self.dev, self.cmd)
        # if (ret != 0):
        #     self.warn_dialog("PCI-6033E cannot collect data! Error: %d" % ret)
        #     print(c.comedi_strerror(c.comedi_errno()))
        #     return(False)
            
        data_tup = ()
        data = ""
        # Format string for struct.unpack()
        format = '32H'

        # See if we can read anything from fd (timeout 0.05 seconds).
        ret = select.select([self.fd], [], [], 0.05)
        if (not ret[0]):
            # Poll the device to try and get some data.
            cret = c.comedi_poll(self.dev, SUBDEVICE)
            if (cret < 0):
                print("comedi poll fail: %d" % ret)
        else:
            # Read some data!
            data = os.read(self.fd, BUF_SIZE)
            self.data_buf += data

        if (len(data) > 0):
            bytes_read = len(data)
            #print("Read %d bytes" % bytes_read)
            # Number of rows of data in the chunk
            r = math.floor(len(self.data_buf)/(self.comedi_num_chans*WORD_SIZE))
            for i in range(int(r)):
                #print(len(data[64*i:64*(i+1)]))
                data_tup = data_tup + struct.unpack(format, self.data_buf[64*i:64*(i+1)])
                #print(data_tup)
                #data_tup = ()
                #print(len(data))
            
            for n, point in enumerate(data_tup):
                self.analog_data[n%self.comedi_num_chans].append(point)
            for i in range(int(r)):
                self.x.append(self.x[-1] + 1.0/SCAN_FREQ)

            self.data_buf = self.data_buf[len(data_tup*2):]
            #print("LEFTOVER DATA:")
            #print(len(self.data_buf))

        return(True)

    def pci_6033e_init(self, dev_name):
        self.dev = c.comedi_open(dev_name)
        if not(self.dev):
            self.warn_dialog("Unable to open device: " + dev_name)
            return(-1)

        ret = c.comedi_lock(self.dev, SUBDEVICE)
        if (ret < 0):
            self.warn_dialog("Could not lock comedi device")
            return(-1)

        # get a file-descriptor for use later
        self.fd = c.comedi_fileno(self.dev)
        if (self.fd <= 0): 
            self.warn_dialog("Error obtaining Comedi device file descriptor")
            c.comedi_close(self.dev)
            return(-1)

        # Channel range (0-5V)
        if (c.comedi_range_is_chan_specific(self.dev, SUBDEVICE) != 0):
            self.warn_dialog("Comedi range is channel specific!")
            c.comedi_close(self.dev)
            return(-1)

        self.comedi_range = c.comedi_get_range(self.dev, SUBDEVICE, 0, CHAN_RANGE)
        self.comedi_maxdata = c.comedi_get_maxdata(self.dev, SUBDEVICE, 0)

        board_name = c.comedi_get_board_name(self.dev)
        if (board_name != "pci-6033e"):
            print("Opened wrong device!")
        
        # Prepare channels, gains, refs
        self.comedi_num_chans = NUM_CHANNELS
        chans = range(self.comedi_num_chans)
        gains = [0]*self.comedi_num_chans
        aref = [c.AREF_GROUND]*self.comedi_num_chans

        chan_list = c.chanlist(self.comedi_num_chans)

        # Configure all the channels!
        for i in range(self.comedi_num_chans):
            chan_list[i] = c.cr_pack(chans[i], gains[i], aref[i])

        # The comedi command
        self.cmd = c.comedi_cmd_struct()

        # 1.0e9 because this number is in nanoseconds for some reason
        period = int(1.0e9/float(SCAN_FREQ))

        # Init cmd
        ret = c.comedi_get_cmd_generic_timed(self.dev, SUBDEVICE, self.cmd, self.comedi_num_chans, period)
        if (ret):
            self.warn_dialog("Could not initiate command")
            c.comedi_close(self.dev)
            return(-1)

        # Populate command 
        self.cmd.chanlist = chan_list
        self.cmd.chanlist_len = self.comedi_num_chans
        self.cmd.scan_end_arg = self.comedi_num_chans
        self.cmd.stop_src = c.TRIG_NONE
        self.cmd.stop_arg = 0

        print("real timing: %d ns" % self.cmd.convert_arg)
        print("Real scan freq: %d Hz" % (1.0/(float(self.cmd.convert_arg)*32.0*1.0e-9)))
        #print("period: %d ns" % period)
    
        print_cmd(self.cmd)

        # Test command out.
        ret = c.comedi_command_test(self.dev, self.cmd)
        if (ret < 0):
            self.warn_dialog("Comedi command test failed!")
            c.comedi_close(self.dev)
            return(-1)

        print("Command test passed")

        return(0)

    # Die gracefully...
    def on_destroy(self, widget):
        if (self.dev):
            c.comedi_close(self.dev)
            print("Comedi device closed...")
        Gtk.main_quit()

    # Oy! 
    def warn_dialog(self, message):
        dialog = Gtk.MessageDialog(self, 0, Gtk.MessageType.WARNING,
                                   Gtk.ButtonsType.OK, "OHNOES!")
        dialog.format_secondary_text(message)
        response = dialog.run()

        # if response == Gtk.ResponseType.OK:
        #     print "WARN dialog closed by clicking OK button"

        dialog.destroy()

    def del_px_data(self, d_x):
        xpx_old, ypx_old = self.a.transData.transform((0, 0))
        xpx_new, ypx_new = self.a.transData.transform((d_x, 0))

        return(xpx_new - xpx_old)

    def update_plots(self):
        if (self.do_redraw):
            #print("redraw")
            self.a.clear()
            self.a.grid(True)
            self.canvas.draw()
            self.clean_bg = self.canvas.copy_from_bbox(self.f.bbox)
            self.background = self.canvas.copy_from_bbox(self.get_bg_bbox(self.a))
            self.do_redraw = False


        self.a.set_xlim([self.x[-1] - self.fifo_size/SCAN_FREQ - 1, self.x[-1] + 1])
        # Restore the blank background
        self.canvas.restore_region(self.clean_bg)

        xarr = np.array(self.x)
        analog_arr = np.array(self.analog_data[0])
        analog_arr2 = np.array(self.analog_data[18])

        #lastx_ind = np.where(np.array(self.x) > self.lastx)
        lastx_ind = np.where(xarr > self.lastx)
        #lastx_ind = itertools.islice(self.lastx

        #print(lastx_ind[0])
        lastx_ind = lastx_ind[0]

        # Offset in time
        x_offset = abs(xarr[-1] - self.lastx)

        # Find the equivalent offset in display pixels
        pixel_offset = self.del_px_data(x_offset)
        dx_pixel = np.floor(pixel_offset)


        # Compute and redraw saved background (moved over).
        x1, y1, x2, y2 = self.background.get_extents()
        self.canvas.restore_region(self.background,
                                   bbox = (x1 + dx_pixel, y1, x2, y2),
                                   xy = (x1 - dx_pixel, y1))

        
        
        # if (len(lastx_ind) > 0):
        #     lastx_ind = np.array(itertools.islice(self.x, lastx_ind[0], self.fifo_size))
        # else:
        #     lastx_ind = np.array(self.x)
        # #print(lastx_ind)

        self.my_line.set_xdata(xarr[lastx_ind])
        self.my_line.set_ydata(analog_arr[lastx_ind])
        self.a.draw_artist(self.my_line)
        #self.canvas.draw()
        self.my_line2.set_xdata(xarr[lastx_ind])
        self.my_line2.set_ydata(analog_arr2[lastx_ind])
        self.a.draw_artist(self.my_line2)

        
        self.background = self.canvas.copy_from_bbox(self.get_bg_bbox(self.a))

        # Draw the axes (and grids if applicable)
        self.a.draw_artist(self.a.xaxis)
        self.a.draw_artist(self.a.yaxis)
        
        self.canvas.blit(self.f.bbox)
        self.lastx = self.x[-1]

        #self.canvas.draw()
        return(True)

    # def init_blit_plot(self):
    #     l = self.line.set_data([], [])
    #     return(l)

    def win_resize(self, win):
        #print("RESIZE!")

        # Don't do this here, instead activate a "needs redraw" class
        # var that instructs update_plot to do a full redraw.

        self.do_redraw = True
class CampaignGraph(object):
	title = 'Unknown'
	_graph_id = None
	table_subscriptions = []
	def __init__(self, config, parent, size_request=None):
		self.config = config
		self.parent = parent
		self.figure, ax = pyplot.subplots()
		self.axes = self.figure.get_axes()
		self.canvas = FigureCanvas(self.figure)
		self.manager = None
		if size_request:
			self.canvas.set_size_request(*size_request)
		self.canvas.mpl_connect('button_press_event', self.mpl_signal_canvas_button_pressed)
		self.canvas.show()
		self.navigation_toolbar = NavigationToolbar(self.canvas, self.parent)
		self.navigation_toolbar.hide()
		self.popup_menu = Gtk.Menu.new()

		menu_item = Gtk.MenuItem.new_with_label('Export')
		menu_item.connect('activate', self.signal_activate_popup_menu_export)
		self.popup_menu.append(menu_item)

		menu_item = Gtk.MenuItem.new_with_label('Refresh')
		menu_item.connect('activate', lambda action: self.refresh())
		self.popup_menu.append(menu_item)

		menu_item = Gtk.CheckMenuItem.new_with_label('Show Toolbar')
		menu_item.connect('toggled', self.signal_toggled_popup_menu_show_toolbar)
		self.popup_menu.append(menu_item)
		self.popup_menu.show_all()

	@classmethod
	def get_graph_id(klass):
		return klass._graph_id

	def make_window(self):
		if self.manager == None:
			self.manager = FigureManager(self.canvas, 0)
		window = self.manager.window
		window.set_transient_for(self.parent)
		window.set_title(self.title)
		return window

	def mpl_signal_canvas_button_pressed(self, event):
		if event.button != 3:
			return
		pos_func = lambda m, d: (event.x, event.y, True)
		self.popup_menu.popup(None, None, None, None, event.button, Gtk.get_current_event_time())
		return True

	def signal_activate_popup_menu_export(self, action):
		dialog = gui_utilities.UtilityFileChooser('Export Graph', self.parent)
		file_name = self.config['campaign_name'] + '.png'
		response = dialog.run_quick_save(file_name)
		dialog.destroy()
		if not response:
			return
		destination_file = response['target_filename']
		self.figure.savefig(destination_file, format='png')

	def signal_toggled_popup_menu_show_toolbar(self, widget):
		if widget.get_property('active'):
			self.navigation_toolbar.show()
		else:
			self.navigation_toolbar.hide()

	def load_graph(self):
		self.refresh()

	def refresh(self, info_cache=None):
		info_cache = (info_cache or {})
		if not self.parent.rpc:
			return info_cache
		for table in self.table_subscriptions:
			if not table in info_cache:
				info_cache[table] = list(self.parent.rpc.remote_table('campaign/' + table, self.config['campaign_id']))
		map(lambda ax: ax.clear(), self.axes)
		self._load_graph(info_cache)
		self.canvas.draw()
		return info_cache
示例#16
0
class MainView(MainViewInterface):

    @inject
    def __init__(self,
                 presenter: MainPresenter,
                 edit_speed_profile_view: EditSpeedProfileView,
                 preferences_view: PreferencesView,
                 builder: MainBuilder,
                 settings_interactor: SettingsInteractor,
                 ) -> None:
        _LOG.debug('init MainView')
        self._presenter: MainPresenter = presenter
        self._edit_speed_profile_view = edit_speed_profile_view
        self._preferences_view = preferences_view
        self._presenter.main_view = self
        self._builder: Gtk.Builder = builder
        self._settings_interactor = settings_interactor
        self._init_widgets()

    def _init_widgets(self) -> None:
        self._app_indicator: Optional[AppIndicator3.Indicator] = None
        self._window = self._builder.get_object("application_window")
        self._edit_speed_profile_view.set_transient_for(self._window)
        self._preferences_view.set_transient_for(self._window)
        self._main_menu: Gtk.Menu = self._builder.get_object("main_menu")
        self._main_infobar: Gtk.InfoBar = self._builder.get_object("main_infobar")
        self._main_infobar.connect("response", lambda b, _: b.set_revealed(False))
        self._main_infobar_label: Gtk.Label = self._builder.get_object("main_infobar_label")
        self._main_infobar.set_revealed(False)
        self._statusbar: Gtk.Statusbar = self._builder.get_object('statusbar')
        self._context = self._statusbar.get_context_id(APP_PACKAGE_NAME)
        self._cooling_fan_duty: Gtk.Label = self._builder.get_object('cooling_fan_duty')
        self._cooling_fan_rpm: Gtk.Label = self._builder.get_object('cooling_fan_rpm')
        self._cooling_liquid_temp: Gtk.Label = self._builder.get_object('cooling_liquid_temp')
        self._cooling_pump_rpm: Gtk.Label = self._builder.get_object('cooling_pump_rpm')
        self._firmware_version: Gtk.Label = self._builder.get_object('firmware_version')
        self._cooling_fan_combobox: Gtk.ComboBox = self._builder.get_object('cooling_fan_profile_combobox')
        self._cooling_fan_liststore: Gtk.ListStore = self._builder.get_object('cooling_fan_profile_liststore')
        self._cooling_pump_combobox: Gtk.ComboBox = self._builder.get_object('cooling_pump_profile_combobox')
        self._cooling_pump_liststore: Gtk.ListStore = self._builder.get_object('cooling_pump_profile_liststore')
        cooling_fan_scrolled_window: Gtk.ScrolledWindow = self._builder.get_object('cooling_fan_scrolled_window')
        cooling_pump_scrolled_window: Gtk.ScrolledWindow = self._builder.get_object('cooling_pump_scrolled_window')
        self._cooling_fan_apply_button: Gtk.Button = self._builder.get_object('cooling_fan_apply_button')
        self._cooling_pump_apply_button: Gtk.Button = self._builder.get_object('cooling_pump_apply_button')
        self._cooling_fan_edit_button: Gtk.Button = self._builder.get_object('cooling_fan_edit_button')
        self._cooling_pump_edit_button: Gtk.Button = self._builder.get_object('cooling_pump_edit_button')
        self._cooling_fixed_speed_popover: Gtk.Popover = self._builder.get_object('cooling_fixed_speed_popover')
        self._cooling_fixed_speed_adjustment: Gtk.Adjustment = \
            self._builder.get_object('cooling_fixed_speed_adjustment')
        self._cooling_fixed_speed_scale: Gtk.Scale = self._builder.get_object('cooling_fixed_speed_scale')
        self._about_dialog: Gtk.AboutDialog = self._builder.get_object("about_dialog")
        self._init_about_dialog()
        self._legacy_firmware_dialog: Gtk.MessageDialog = self._builder.get_object("legacy_firmware_dialog")
        self._legacy_firmware_dialog.connect('response', lambda dialog, _: dialog.hide())
        self._init_plot_charts(cooling_fan_scrolled_window, cooling_pump_scrolled_window)

    def _init_about_dialog(self) -> None:
        self._about_dialog.set_program_name(APP_NAME)
        self._about_dialog.set_version(APP_VERSION)
        self._about_dialog.set_website(APP_SOURCE_URL)
        self._about_dialog.connect("delete-event", hide_on_delete)

    def show(self) -> None:
        self._presenter.on_start()
        self._init_app_indicator()

    def _init_app_indicator(self) -> None:
        if AppIndicator3:
            # Setting icon name in new() as '', because new() wants an icon path
            self._app_indicator = AppIndicator3.Indicator \
                .new(APP_ID, '', AppIndicator3.IndicatorCategory.HARDWARE)
            # Set the actual icon by name. If the App is not installed system-wide, the icon won't show up,
            # otherwise it will show up correctly. The set_icon_full() function needs a description for accessibility
            # purposes. I gave it the APP_NAME.
            self._app_indicator.set_icon_full(APP_ICON_NAME_SYMBOLIC, APP_NAME)
            if self._settings_interactor.get_bool('settings_show_app_indicator'):
                self._app_indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
            else:
                self._app_indicator.set_status(AppIndicator3.IndicatorStatus.PASSIVE)
            self._app_indicator.set_menu(self._main_menu)

    def show_main_infobar_message(self, message: str, markup: bool = False) -> None:
        if markup:
            self._main_infobar_label.set_markup(message)
        else:
            self._main_infobar_label.set_label(message)
        self._main_infobar.set_revealed(True)

    def toggle_window_visibility(self) -> None:
        if self._window.props.visible:
            self._window.hide()
        else:
            self._window.show()

    def show_add_speed_profile_dialog(self, channel: ChannelType) -> None:
        _LOG.debug("view show_add_speed_profile_dialog %s", channel.name)

    def show_fixed_speed_profile_popover(self, profile: SpeedProfile) -> None:
        if profile.channel == ChannelType.FAN.value:
            self._cooling_fixed_speed_popover.set_relative_to(self._cooling_fan_edit_button)
            self._cooling_fixed_speed_adjustment.set_lower(FAN_MIN_DUTY)
            self._cooling_fixed_speed_adjustment.set_upper(MAX_DUTY)
        elif profile.channel == ChannelType.PUMP.value:
            self._cooling_fixed_speed_popover.set_relative_to(self._cooling_pump_edit_button)
            self._cooling_fixed_speed_adjustment.set_lower(PUMP_MIN_DUTY)
            self._cooling_fixed_speed_adjustment.set_upper(MAX_DUTY)
        else:
            raise ValueError("Unknown channel: %s" % profile.channel)
        self._cooling_fixed_speed_scale.set_name(profile.channel)
        self._cooling_fixed_speed_adjustment.set_value(profile.steps[0].duty)
        self._cooling_fixed_speed_popover.show_all()

    def dismiss_and_get_value_fixed_speed_popover(self) -> Tuple[int, str]:
        self._cooling_fixed_speed_popover.hide()
        return self._cooling_fixed_speed_scale.get_value(), self._cooling_fixed_speed_scale.get_name()

    def show_about_dialog(self) -> None:
        self._about_dialog.show()

    def show_legacy_firmware_dialog(self) -> None:
        self._legacy_firmware_dialog.show()

    def show_error_message_dialog(self, title: str, message: str) -> None:
        dialog = Gtk.MessageDialog(self._window, 0, Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, title)
        dialog.format_secondary_text(message)
        dialog.run()
        dialog.destroy()

    def set_statusbar_text(self, text: str) -> None:
        self._statusbar.remove_all(self._context)
        self._statusbar.push(self._context, text)

    def refresh_status(self, status: Optional[Status]) -> None:
        _LOG.debug('view status')
        if status:
            self._cooling_fan_rpm.set_markup("<span size=\"xx-large\">%s</span> RPM" % status.fan_rpm)
            self._cooling_fan_duty.set_markup("<span size=\"xx-large\">%s</span> %%" %
                                              ('-' if status.fan_duty is None else "%.0f" % status.fan_duty))
            self._cooling_liquid_temp.set_markup("<span size=\"xx-large\">%s</span> °C" % status.liquid_temperature)
            self._cooling_pump_rpm.set_markup("<span size=\"xx-large\">%s</span> RPM" % status.pump_rpm)
            self._firmware_version.set_label("firmware %s - %s %s"
                                             % (status.firmware_version, APP_NAME, APP_VERSION))
            if self._app_indicator:
                if self._settings_interactor.get_bool('settings_show_app_indicator'):
                    self._app_indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
                else:
                    self._app_indicator.set_status(AppIndicator3.IndicatorStatus.PASSIVE)
                if self._settings_interactor.get_bool('settings_app_indicator_show_water_temp'):
                    self._app_indicator.set_label("  %s°C" % status.liquid_temperature, "  XX°C")
                else:
                    self._app_indicator.set_label("", "")

    def refresh_chart(self, profile: Optional[SpeedProfile] = None, channel_to_reset: Optional[str] = None) -> None:
        if profile is None and channel_to_reset is None:
            raise ValueError("Both parameters are None!")

        if channel_to_reset is not None:
            self._plot_chart(channel_to_reset, {})
        else:
            self._plot_chart(profile.channel, get_speed_profile_data(profile))

    def refresh_profile_combobox(self, channel: ChannelType, data: List[Tuple[int, str]],
                                 active: Optional[int]) -> None:
        if channel is ChannelType.FAN:
            self._cooling_fan_liststore.clear()
            for item in data:
                self._cooling_fan_liststore.append([item[0], item[1]])
            self._cooling_fan_combobox.set_model(self._cooling_fan_liststore)
            self._cooling_fan_combobox.set_sensitive(len(self._cooling_fan_liststore) > 1)
            if active is not None:
                self._cooling_fan_combobox.set_active(active)
            else:
                self.refresh_chart(channel_to_reset=channel.value)
        elif channel is ChannelType.PUMP:
            self._cooling_pump_liststore.clear()
            for item in data:
                self._cooling_pump_liststore.append([item[0], item[1]])
            self._cooling_pump_combobox.set_model(self._cooling_pump_liststore)
            self._cooling_pump_combobox.set_sensitive(len(self._cooling_pump_liststore) > 1)
            if active is not None:
                self._cooling_pump_combobox.set_active(active)
            else:
                self.refresh_chart(channel_to_reset=channel.value)
        else:
            raise ValueError("Unknown channel: %s" % channel.name)

    def set_apply_button_enabled(self, channel: ChannelType, enabled: bool) -> None:
        if channel is ChannelType.FAN:
            self._cooling_fan_apply_button.set_sensitive(enabled)
        elif channel is ChannelType.PUMP:
            self._cooling_pump_apply_button.set_sensitive(enabled)
        else:
            raise ValueError("Unknown channel: %s" % channel.name)

    def set_edit_button_enabled(self, channel: ChannelType, enabled: bool) -> None:
        if channel is ChannelType.FAN:
            self._cooling_fan_edit_button.set_sensitive(enabled)
        elif channel is ChannelType.PUMP:
            self._cooling_pump_edit_button.set_sensitive(enabled)
        else:
            raise ValueError("Unknown channel: %s" % channel.name)

    # pylint: disable=attribute-defined-outside-init
    def _init_plot_charts(self,
                          fan_scrolled_window: Gtk.ScrolledWindow,
                          pump_scrolled_window: Gtk.ScrolledWindow) -> None:
        self._fan_figure = Figure(figsize=(8, 6), dpi=72, facecolor='#00000000')
        self._fan_canvas = FigureCanvas(self._fan_figure)  # a Gtk.DrawingArea+
        self._fan_axis = self._fan_figure.add_subplot(111)
        self._fan_line, = init_plot_chart(
            fan_scrolled_window,
            self._fan_figure,
            self._fan_canvas,
            self._fan_axis
        )

        self._pump_figure = Figure(figsize=(8, 6), dpi=72, facecolor='#00000000')
        self._pump_canvas = FigureCanvas(self._pump_figure)  # a Gtk.DrawingArea+
        self._pump_axis = self._pump_figure.add_subplot(111)
        self._pump_line, = init_plot_chart(
            pump_scrolled_window,
            self._pump_figure,
            self._pump_canvas,
            self._pump_axis
        )

    def _plot_chart(self, channel_name: str, data: Dict[int, int]) -> None:
        sorted_data = OrderedDict(sorted(data.items()))
        temperature = list(sorted_data.keys())
        duty = list(sorted_data.values())
        if channel_name == ChannelType.FAN.value:
            self._fan_line.set_xdata(temperature)
            self._fan_line.set_ydata(duty)
            self._fan_canvas.draw()
            self._fan_canvas.flush_events()
        elif channel_name == ChannelType.PUMP.value:
            self._pump_line.set_xdata(temperature)
            self._pump_line.set_ydata(duty)
            self._pump_canvas.draw()
            self._pump_canvas.flush_events()
        else:
            raise ValueError("Unknown channel: %s" % channel_name)
示例#17
0
文件: gui.py 项目: edumur/paramp
class Window(object):

    def __init__(self):


        self.builder = Gtk.Builder()
        self.builder.add_from_file('gui.glade')
        self.window = self.builder.get_object('window1')
        self.builder.connect_signals(self)
        figure_box = self.builder.get_object('scrolledwindow1')

        self.builder.get_object('spinbuttonphi_s').set_increments(0.005, 0.1)
        self.builder.get_object('spinbuttonphi_p').set_increments(0.005, 0.1)
        self.builder.get_object('spinbuttonL_b').set_increments(0.001, 0.1)
        self.simple_ext = False
        self.freeze_plot = False

        self.paramp = LJPA(I_c=self.builder.get_object('spinbuttonI_c').get_value()*1e-6,
                           phi_dc=self.builder.get_object('spinbuttonphi_dc').get_value(),
                           phi_ac=self.builder.get_object('spinbuttonphi_p').get_value(),
                           phi_s=self.builder.get_object('spinbuttonphi_s').get_value(),
                           theta_p=self.builder.get_object('spinbuttontheta_p').get_value(),
                           C=self.builder.get_object('spinbuttonC').get_value()*1e-12,
                           L_s=self.builder.get_object('spinbuttonL_s').get_value()*1e-12,
                           f_p=self.builder.get_object('spinbuttonf_p').get_value()*1e9)

        self.parameters = {'I_c' : self.builder.get_object('spinbuttonI_c').get_value()*1e-6,
                           'phi_dc' : self.builder.get_object('spinbuttonphi_dc').get_value(),
                           'phi_ac' : self.builder.get_object('spinbuttonphi_p').get_value(),
                           'phi_s' : self.builder.get_object('spinbuttonphi_s').get_value(),
                           'theta_p' : self.builder.get_object('spinbuttontheta_p').get_value(),
                           'C' : self.builder.get_object('spinbuttonC').get_value()*1e-12,
                           'L_s' : self.builder.get_object('spinbuttonL_s').get_value()*1e-12,
                           'f_p' : self.builder.get_object('spinbuttonf_p').get_value()*1e9}

        self.builder.get_object('entry1').set_text(str(self.parameters))

        # Start of Matplotlib specific code
        self.fig, (self.ax1, self.ax2, self.ax3, self.ax4) = plt.subplots(4, 1, sharex=True)
        # figure = Figure()#figsize=(8, 6), dpi=71)
        # self.ax = figure.add_subplot(111)

        f = self.get_frequency()
        z = self.get_impedance(f)
        re = np.real(z)
        im = np.imag(z)
        r = 20.*np.log10(abs((z - 50.)/(z + 50.)))

        self.line_r,  = self.ax1.plot(f/1e9, r)
        self.line_20, = self.ax1.plot([f[0]/1e9, f[-1.]/1e9], [20., 20.], 'r--')

        self.line_re, = self.ax2.plot(f/1e9, re)
        self.line_50, = self.ax2.plot([f[0]/1e9, f[-1.]/1e9], [-50., -50.], 'r--')

        self.line_im, = self.ax3.plot(f/1e9, im)
        self.line_0, = self.ax3.plot([f[0]/1e9, f[-1.]/1e9], [0., 0.], 'r--')

        self.line_abs, = self.ax4.plot(f/1e9, abs(z))
        self.line_00, = self.ax4.plot([f[0]/1e9, f[-1.]/1e9], [0., 0.], 'r--')

        self.ax1.set_ylabel('Gain [dB]')
        self.ax2.set_ylabel('Re(Z)')
        self.ax3.set_ylabel('Im(Z)')
        self.ax4.set_ylabel('|Z|')

        self.ax4.set_xlabel('Frequency [GHz]')

        self.canvas = FigureCanvas(self.fig)

        self.canvas.set_size_request(800, 600)
        figure_box.add_with_viewport(self.canvas)

        toolbar_box = self.builder.get_object('scrolledwindow2')
        toolbar = NavigationToolbar(self.canvas, self.window)
        toolbar_box.add_with_viewport(toolbar)

        self.window.show_all()

        Gtk.main()



    def get_frequency(self):

        return np.linspace(self.builder.get_object('spinbuttonf_s_start').get_value(),
                           self.builder.get_object('spinbuttonf_s_stop').get_value(),
                           self.builder.get_object('spinbuttonf_s_nb_point').get_value())*1e9


    def get_impedance(self, f):

        if self.builder.get_object('checkbutton3').get_active():

            return self.paramp.impedance(f, simple_ext=self.simple_ext)
        else:

            return self.paramp.impedance(f)


    def checkbutton1_toggled(self, checkbutton):

        if checkbutton.get_active():
            self.builder.get_object('box11').set_sensitive(True)
            self.builder.get_object('box20').set_sensitive(False)
            self.paramp.f_p = self.builder.get_object('spinbuttonf_p').get_value()*1e9
        else:
            self.builder.get_object('box11').set_sensitive(False)
            self.builder.get_object('box20').set_sensitive(True)
            self.paramp.f_p = None

        self.update_plot()



    def checkbutton3_toggled(self, checkbutton):

        if checkbutton.get_active():
            self.simple_ext = True
        else:
            self.simple_ext = False

        self.update_plot()



    def checkbutton2_toggled(self, checkbutton):

        if checkbutton.get_active():

            self.builder.get_object('box21').set_sensitive(True)
            self.builder.get_object('box25').set_sensitive(True)
            self.builder.get_object('box26').set_sensitive(True)
            self.builder.get_object('box27').set_sensitive(True)
            self.builder.get_object('checkbutton3').set_sensitive(True)
            self.builder.get_object('box31').set_sensitive(True)
            self.builder.get_object('box30').set_sensitive(True)
            self.builder.get_object('box29').set_sensitive(True)
            self.builder.get_object('box28').set_sensitive(True)
            self.builder.get_object('box13').set_sensitive(True)
            self.builder.get_object('box8').set_sensitive(True)
            self.builder.get_object('label35').set_sensitive(True)
            self.builder.get_object('label31').set_sensitive(True)
            self.builder.get_object('button1').set_sensitive(True)

            self.paramp = KLJPA(I_c=self.builder.get_object('spinbuttonI_c').get_value()*1e-6,
                               phi_dc=self.builder.get_object('spinbuttonphi_dc').get_value(),
                               phi_ac=self.builder.get_object('spinbuttonphi_p').get_value(),
                               phi_s=self.builder.get_object('spinbuttonphi_s').get_value(),
                               theta_p=self.builder.get_object('spinbuttontheta_p').get_value(),
                               C=self.builder.get_object('spinbuttonC').get_value()*1e-12,
                               L_s=self.builder.get_object('spinbuttonL_s').get_value()*1e-12,
                               f_p=self.builder.get_object('spinbuttonf_p').get_value()*1e9,
                                Z_l=self.builder.get_object('spinbuttonz_l').get_value(),
                                l=self.builder.get_object('spinbuttonl').get_value()*1e-2,
                                g_m=self.builder.get_object('spinbuttong_m').get_value(),
                                C_l=1.66e-10,
                                L_l=4.21e-7,
                                L_b=self.builder.get_object('spinbuttonL_b').get_value()*1e-9)

            self.builder.get_object('entry1').set_text(str(self.parameters))

        else:

            self.builder.get_object('box21').set_sensitive(False)
            self.builder.get_object('box25').set_sensitive(False)
            self.builder.get_object('box26').set_sensitive(False)
            self.builder.get_object('box27').set_sensitive(False)
            self.builder.get_object('checkbutton3').set_sensitive(False)
            self.builder.get_object('box31').set_sensitive(False)
            self.builder.get_object('box30').set_sensitive(False)
            self.builder.get_object('box29').set_sensitive(False)
            self.builder.get_object('box28').set_sensitive(False)
            self.builder.get_object('box13').set_sensitive(False)
            self.builder.get_object('box8').set_sensitive(False)
            self.builder.get_object('label35').set_sensitive(False)
            self.builder.get_object('label31').set_sensitive(False)
            self.builder.get_object('button1').set_sensitive(False)

            self.paramp = LJPA(I_c=self.builder.get_object('spinbuttonI_c').get_value()*1e-6,
                               phi_dc=self.builder.get_object('spinbuttonphi_dc').get_value(),
                               phi_ac=self.builder.get_object('spinbuttonphi_p').get_value(),
                               phi_s=self.builder.get_object('spinbuttonphi_s').get_value(),
                               theta_p=self.builder.get_object('spinbuttontheta_p').get_value(),
                               C=self.builder.get_object('spinbuttonC').get_value()*1e-12,
                               L_s=self.builder.get_object('spinbuttonL_s').get_value()*1e-12,
                               f_p=self.builder.get_object('spinbuttonf_p').get_value()*1e9)

        self.update_plot()


    def button2_clicked(self, button):

        p = eval(self.builder.get_object('entry1').get_text())

        self.freeze_plot = True
        self.builder.get_object('spinbuttonI_c').set_value(p['I_c']*1e6)
        self.builder.get_object('spinbuttonphi_dc').set_value(p['phi_dc'])
        self.builder.get_object('spinbuttonphi_p').set_value(p['phi_ac'])
        self.builder.get_object('spinbuttonphi_s').set_value(p['phi_s'])
        self.builder.get_object('spinbuttontheta_p').set_value(p['theta_p'])
        self.builder.get_object('spinbuttonC').set_value(p['C']*1e12)
        self.builder.get_object('spinbuttonL_s').set_value(p['L_s']*1e12)
        self.builder.get_object('spinbuttonf_p').set_value(p['f_p']*1e-9)
        self.builder.get_object('spinbuttonz_l').set_value(p['Z_l'])
        self.builder.get_object('spinbuttonl').set_value(p['l']*1e2)
        self.builder.get_object('spinbuttong_m').set_value(p['g_m'])
        self.builder.get_object('spinbuttonL_b').set_value(p['L_b']*1e9)
        self.freeze_plot = False

        self.update_plot()


    def spinbuttonC_changed(self, spinbutton):

        self.paramp.C = spinbutton.get_value()*1e-12

        self.update_plot()



    def spinbuttonI_c_changed(self, spinbutton):

        self.paramp.I_c = spinbutton.get_value()*1e-6

        self.update_plot()



    def spinbuttonL_s_changed(self, spinbutton):

        self.paramp.L_s = spinbutton.get_value()*1e-12

        self.update_plot()



    def spinbuttonf_p_changed(self, spinbutton):

        self.paramp.f_p = spinbutton.get_value()*1e9

        self.update_plot()



    def spinbuttonphi_p_changed(self, spinbutton):

        self.paramp.phi_ac = spinbutton.get_value()

        self.update_plot()



    def spinbuttontheta_p_changed(self, spinbutton):

        self.paramp.theta_p = spinbutton.get_value()

        self.update_plot()



    def spinbuttonphi_s_changed(self, spinbutton):

        self.paramp.phi_s = spinbutton.get_value()*1e-3

        self.update_plot()



    def spinbuttonphi_dc_changed(self, spinbutton):

        self.paramp.phi_dc = spinbutton.get_value()

        self.update_plot()



    def spinbuttonl_changed(self, spinbutton):

        self.paramp.l = spinbutton.get_value()*1e-2

        self.update_plot()



    def spinbuttonz_l_changed(self, spinbutton):

        self.paramp.zl = spinbutton.get_value()

        self.update_plot()



    def spinbuttong_m_changed(self, spinbutton):

        self.paramp.gm = spinbutton.get_value()

        self.update_plot()



    def spinbuttonL_b_changed(self, spinbutton):

        self.paramp.L_b = spinbutton.get_value()*1e-9

        self.update_plot()



    def spinbuttonf_s_nb_point_changed(self, spinbutton):

        self.update_plot()



    def spinbuttonf_s_start_changed(self, spinbutton):

        self.update_plot()



    def spinbuttonf_s_stop_changed(self, spinbutton):

        self.update_plot()



    def update_plot(self, x=None, y=None):

        if not self.freeze_plot:

            if x is not None and y is not None:
                f = x
                z = y
            else:
                f = self.get_frequency()
                z = self.get_impedance(f)

            re = np.real(z)
            im = np.imag(z)
            r = 20.*np.log10(abs((z - 50.)/(z + 50.)))

            self.line_r.set_data(f/1e9, r)
            self.line_20.set_data(f/1e9, r)

            self.line_re.set_data(f/1e9, re)
            self.line_50.set_data([f[0]/1e9, f[-1.]/1e9], [-50., -50.])

            self.line_im.set_data(f/1e9, im)
            self.line_0.set_data([f[0]/1e9, f[-1.]/1e9], [0., 0.])

            self.line_abs.set_data(f/1e9, abs(z))
            self.line_00.set_data([f[0]/1e9, f[-1.]/1e9], [0., 0.])

            for ax in (self.ax1, self.ax2, self.ax3, self.ax4):

                ax.relim()
                ax.autoscale_view()

            self.line_20.set_data([f[0]/1e9, f[-1.]/1e9], [20., 20.])
            self.canvas.draw()

        if self.builder.get_object('checkbutton2').get_active():

            self.parameters = {'I_c' : self.builder.get_object('spinbuttonI_c').get_value()*1e-6,
                               'phi_dc' : self.builder.get_object('spinbuttonphi_dc').get_value(),
                               'phi_ac' : self.builder.get_object('spinbuttonphi_p').get_value(),
                               'phi_s' : self.builder.get_object('spinbuttonphi_s').get_value(),
                               'theta_p' : self.builder.get_object('spinbuttontheta_p').get_value(),
                               'C' : self.builder.get_object('spinbuttonC').get_value()*1e-12,
                               'L_s' : self.builder.get_object('spinbuttonL_s').get_value()*1e-12,
                               'f_p' : self.builder.get_object('spinbuttonf_p').get_value()*1e9,
                               'Z_l' : self.builder.get_object('spinbuttonz_l').get_value(),
                               'l' : self.builder.get_object('spinbuttonl').get_value()*1e-2,
                               'g_m' : self.builder.get_object('spinbuttong_m').get_value(),
                               'C_l' : 1.66e-10,
                               'L_l' : 4.21e-7,
                               'L_b' : self.builder.get_object('spinbuttonL_b').get_value()*1e-9}
        else:

            self.parameters = {'I_c' : self.builder.get_object('spinbuttonI_c').get_value()*1e-6,
                               'phi_dc' : self.builder.get_object('spinbuttonphi_dc').get_value(),
                               'phi_ac' : self.builder.get_object('spinbuttonphi_p').get_value(),
                               'phi_s' : self.builder.get_object('spinbuttonphi_s').get_value(),
                               'theta_p' : self.builder.get_object('spinbuttontheta_p').get_value(),
                               'C' : self.builder.get_object('spinbuttonC').get_value()*1e-12,
                               'L_s' : self.builder.get_object('spinbuttonL_s').get_value()*1e-12,
                               'f_p' : self.builder.get_object('spinbuttonf_p').get_value()*1e9}


        self.builder.get_object('entry1').set_text(str(self.parameters))


    def optimization(self, button):

        self.iteration = 0
        def func(x, names, f):

            x = abs(x)

            for value, name in zip(x, names):

                if name == 'c':
                    self.paramp.C = value*1e-12
                if name == 'Ic':
                    self.paramp.I_c = value*1e-6
                if name == 'Ls':
                    self.paramp.L_s = value*1e-12
                if name == 'l':
                    self.paramp.l = value*1e-2
                if name == 'zl':
                    self.paramp.zl = value
                if name == 'gm':
                    self.paramp.gm = value*1e-1
                if name == 'lb':
                    self.paramp.L_b = value*1e-1
                if name == 'fp':
                    self.paramp.f_p = value*1e9
                if name == 'phi_ac':
                    self.paramp.phi_ac = value*1e-1
                if name == 'phi_dc':
                    self.paramp.phi_dc = value*1e-1

            z = self.get_impedance(f)

            re = np.real(z)
            im = np.imag(z)

            re_condition = np.sum(((re + 50.)/re)**2.)
            im_condition = np.sum((im/100.)**2.)

            y =  np.sum(((re + 50.)/re)**2. + (im/100.)**2.)
            self.iteration += 1

            print ''
            print 'Iteration: ', self.iteration
            for value, name in zip(x, names):
                if name == 'c':
                    print 'C: '+str(round(self.paramp.C*1e12, 3))
                if name == 'Ic':
                    print 'Ic: '+str(round(self.paramp.I_c*1e6, 3))
                if name == 'Ls':
                    print 'L_s: '+str(round(self.paramp.L_s*1e12, 3))
                if name == 'l':
                    print 'l: '+str(round(self.paramp.l*1e2, 3))
                if name == 'zl':
                    print 'zl: '+str(round(self.paramp.zl, 3))
                if name == 'gm':
                    print 'gm: '+str(round(self.paramp.gm, 3))
                if name == 'lb':
                    print 'L_b: '+str(round(self.paramp.L_b*1e9, 3))
                if name == 'fp':
                    print 'f_p: '+str(round(self.paramp.f_p*1e-9, 3))
                if name == 'phi_ac':
                    print 'phi_ac: '+str(round(self.paramp.phi_ac, 3))
                if name == 'phi_dc':
                    print 'phi_dc: '+str(round(self.paramp.phi_dc, 3))
            print 'Real part: '+str(round(re_condition, 3))+', imaginary part: '+str(round(im_condition, 3))+', least square: '+str(round(y, 3))
            print ''

            return y


        names  = ['c', 'Ic', 'Ls', 'l', 'zl', 'gm', 'lb', 'fp', 'phi_ac', 'phi_dc']
        values = [self.builder.get_object('spinbuttonC').get_value(),
                  self.builder.get_object('spinbuttonI_c').get_value(),
                  self.builder.get_object('spinbuttonL_s').get_value(),
                  self.builder.get_object('spinbuttonl').get_value(),
                  self.builder.get_object('spinbuttonz_l').get_value(),
                  self.builder.get_object('spinbuttong_m').get_value()*10.,
                  self.builder.get_object('spinbuttonL_b').get_value()*10.,
                  self.builder.get_object('spinbuttonf_p').get_value(),
                  self.builder.get_object('spinbuttonphi_p').get_value()*10.,
                  self.builder.get_object('spinbuttonphi_dc').get_value()*10.]
        bounds = ((2., 8.),
                  (2., 6.),
                  (20., 30.),
                  (0.5, 4.),
                  (3., 20.),
                  (0.01, 5),
                  (0.01, 20.),
                  (5., 20.),
                  (0.1, 9.),
                  (1., 4.))


        variables = []
        if self.builder.get_object('checkbutton_optimized_c').get_active():
            variables.append('c')
        if self.builder.get_object('checkbutton_optimized_Ic').get_active():
            variables.append('Ic')
        if self.builder.get_object('checkbutton_optimized_ls').get_active():
            variables.append('Ls')
        if self.builder.get_object('checkbutton_optimized_l').get_active():
            variables.append('l')
        if self.builder.get_object('checkbutton_optimized_zl').get_active():
            variables.append('zl')
        if self.builder.get_object('checkbutton_optimized_gm').get_active():
            variables.append('gm')
        if self.builder.get_object('checkbutton_optimized_lb').get_active():
            variables.append('lb')
        if self.builder.get_object('checkbutton_optimized_fp').get_active():
            variables.append('fp')
        if self.builder.get_object('checkbutton_optimized_phi_ac').get_active():
            variables.append('phi_ac')
        if self.builder.get_object('checkbutton_optimized_phi_dc').get_active():
            variables.append('phi_dc')

        names_to_optimized  = []
        values_to_optimized = []
        bounds_to_optimized = []

        for name, value, bound in zip(names, values, bounds):
            if name in variables:
                names_to_optimized.append(name)
                values_to_optimized.append(value)
                bounds_to_optimized.append(bound)

        f = np.linspace(self.builder.get_object('spinbutton1').get_value(),
                        self.builder.get_object('spinbutton2').get_value(),
                        self.builder.get_object('spinbutton3').get_value())*1e9

        self.freeze_plot = True
        results = minimize(func,
                           values_to_optimized,
                           args=(names_to_optimized, f),
                        #    method='TNC',
                           method='SLSQP',
                        #    method='L-BFGS-B',
                           bounds=bounds_to_optimized)
        values_optimized = results.x

        self.freeze_plot = False

        for value, name in zip(values_optimized, names_to_optimized):
            if name == 'c':
                self.builder.get_object('spinbuttonC').set_value(value)
            if name == 'Ic':
                self.builder.get_object('spinbuttonI_c').set_value(value)
            if name == 'Ls':
                self.builder.get_object('spinbuttonL_s').set_value(value)
            if name == 'l':
                self.builder.get_object('spinbuttonl').set_value(value)
            if name == 'zl':
                self.builder.get_object('spinbuttonz_l').set_value(value)
            if name == 'gm':
                self.builder.get_object('spinbuttong_m').set_value(value/10.)
            if name == 'lb':
                self.builder.get_object('spinbuttonL_b').set_value(value/10.)
            if name == 'fp':
                self.builder.get_object('spinbuttonf_p').set_value(value)
            if name == 'phi_ac':
                self.builder.get_object('spinbuttonphi_p').set_value(value/10.)
            if name == 'phi_dc':
                self.builder.get_object('spinbuttonphi_dc').set_value(value/10.)

        self.update_plot()
        print 'Done'
        return True




    def quit(self, event):

        Gtk.main_quit()
示例#18
0
class PlotWindow(Gtk.Window):
    __gsignals__ = {
        'click_on_plot': (GObject.SIGNAL_RUN_FIRST, None, (float, ))
    }

    def __init__(self):
        super().__init__(title="Yaw Pitch Roll Plot")
        self.window_closed = False
        self.connect('destroy', self.on_destroy)
        self.f = Figure(figsize=(5, 4), dpi=100)
        self.canvas = FigureCanvas(self.f)
        self.f.canvas.mpl_connect('pick_event', self.on_pick)
        vbox = Gtk.VBox()
        self.add(vbox)
        vbox.pack_start(self.canvas, True, True, 0)
        toolbar = NavigationToolbar(self.canvas, self)
        vbox.pack_start(toolbar, False, False, 0)
        self.set_size_request(750, 600)
        self.axarr = None
        self.video_length_plots = [None] * 4
        self.yaw_time = None
        self.pitch_time = None
        self.roll_time = None
        self.height_time = None
        self.start_time_stamp = None
        self.video_list = None
        self.show_all()

    def on_destroy(self, *_):
        self.window_closed = True

    def plot(self, time_stamps, data, video_list):
        self.video_list = video_list
        self.start_time_stamp = time_stamps[0]
        time = [t - time_stamps[0] for t in time_stamps]
        yaw, pitch, roll, height = zip(*data)
        self.axarr = self.f.subplots(nrows=2, ncols=2)
        self.plot_yaw(self.axarr, yaw, time)
        self.plot_pitch(self.axarr, pitch, time)
        self.plot_roll(self.axarr, roll, time)
        self.plot_height(self.axarr, height, time)

    @staticmethod
    def shift_yaw(yaw):
        new_yaw = []
        last_point = 0
        shift = 0
        for point in yaw:
            if (last_point > 150 and point < -150) or (last_point < -150
                                                       and point > 150):
                if point < 0:
                    shift += 360
                else:
                    shift -= 360
            new_point = point + shift
            last_point = point
            new_yaw.append(new_point)
        return new_yaw

    def plot_yaw(self, axarr, yaw, time):
        new_yaw = self.shift_yaw(yaw)
        for offset in range(-10 * 360, 10 * 360 + 1, 360):
            yaw_with_offset = [x + offset for x in new_yaw]
            axarr[0, 0].plot(time, yaw_with_offset, 'blue')
        axarr[0, 0].set_ylim([-200, 200])
        axarr[0, 0].set_xlim([0, time[-1]])
        axarr[0, 0].set_xlabel('Seconds')
        axarr[0, 0].set_ylabel('Degrees')
        axarr[0, 0].xaxis.set_ticks(np.arange(0, time[-1], 60))
        for video in self.video_list:
            axarr[0, 0].axvspan(xmin=video[0] - self.start_time_stamp,
                                xmax=video[1] - self.start_time_stamp,
                                color='#bbbbbb',
                                picker=1)
        self.yaw_time = axarr[0, 0].axvline(x=0, color='red', linewidth=2)
        axarr[0, 0].set_title('Yaw')

    def plot_pitch(self, axarr, pitch, time):
        axarr[0, 1].plot(time, pitch, 'blue')
        axarr[0, 1].set_ylim([-100, 30])
        axarr[0, 1].set_xlim([0, time[-1]])
        axarr[0, 1].set_xlabel('Seconds')
        axarr[0, 1].set_ylabel('Degrees')
        axarr[0, 1].xaxis.set_ticks(np.arange(0, time[-1], 60))
        for video in self.video_list:
            axarr[0, 1].axvspan(xmin=video[0] - self.start_time_stamp,
                                xmax=video[1] - self.start_time_stamp,
                                color='#bbbbbb',
                                picker=1)
        self.pitch_time = axarr[0, 1].axvline(x=0, color='red', linewidth=2)
        axarr[0, 1].set_title('Pitch')

    def plot_roll(self, axarr, roll, time):
        axarr[1, 1].plot(time, roll, 'blue')
        axarr[1, 1].set_ylim([-180, 180])
        axarr[1, 1].set_xlim([0, time[-1]])
        axarr[1, 1].set_xlabel('Seconds')
        axarr[1, 1].set_ylabel('Degrees')
        axarr[1, 1].xaxis.set_ticks(np.arange(0, time[-1], 60))
        for video in self.video_list:
            axarr[1, 1].axvspan(xmin=video[0] - self.start_time_stamp,
                                xmax=video[1] - self.start_time_stamp,
                                color='#bbbbbb',
                                picker=1)
        self.roll_time = axarr[1, 1].axvline(x=0, color='red', linewidth=2)
        axarr[1, 1].set_title('Roll')

    def plot_height(self, axarr, height, time):
        axarr[1, 0].plot(time, height, 'blue')
        axarr[1, 0].set_xlim([0, time[-1]])
        axarr[1, 0].set_xlabel('Seconds')
        axarr[1, 0].set_ylabel('Meters')
        axarr[1, 0].xaxis.set_ticks(np.arange(0, time[-1], 60))
        ylim = axarr[1, 0].get_ylim()
        for video in self.video_list:
            axarr[1, 0].axvspan(xmin=video[0] - self.start_time_stamp,
                                xmax=video[1] - self.start_time_stamp,
                                color='#bbbbbb',
                                picker=1)
        self.height_time = axarr[1, 0].axvline(x=0, color='red', linewidth=2)
        axarr[1, 0].set_ylim(ylim)
        axarr[1, 0].set_title('Height')

    def update_plot(self, time):
        self.yaw_time.set_xdata(time)
        self.pitch_time.set_xdata(time)
        self.roll_time.set_xdata(time)
        self.height_time.set_xdata(time)
        self.canvas.draw()
        self.canvas.flush_events()

    def update_video_length_plot(self, video_start, video_length):
        for plot in self.video_length_plots:
            if plot:
                plot.remove()
        self.video_length_plots = [
            self.axarr[x, y].axvspan(xmin=video_start,
                                     xmax=video_start + video_length,
                                     ymin=0,
                                     ymax=0.1,
                                     color='#99ff99')
            for x, y in product(range(2), range(2))
        ]

    def on_pick(self, event):
        video_start = np.min(event.artist.get_xy(), axis=0)[0]
        self.emit('click_on_plot', video_start)
示例#19
0
文件: img.py 项目: ke8ctn/gtknodes
class PlotNode(GtkNodes.Node):
    __gtype_name__ = 'PlotNode'

    def __init__(self, *args, **kwds):
        super().__init__(*args, **kwds)

        self.val_1 = 0
        self.val_2 = 4
        self.val_3 = 12

        self.set_label("Plot")

        self.connect("node_func_clicked", self.remove)

        # create node input socket 1
        lbl = Gtk.Label.new("Input 1")
        lbl.set_xalign(0.1)
        node_socket_input = self.item_add(lbl, GtkNodes.NodeSocketIO.SINK)
        node_socket_input.connect("socket_incoming", self.node_socket_incoming,
                                  1)

        # create nodeinput socket 2
        lbl = Gtk.Label.new("Input 2")
        lbl.set_xalign(0.1)
        node_socket_input = self.item_add(lbl, GtkNodes.NodeSocketIO.SINK)
        node_socket_input.connect("socket_incoming", self.node_socket_incoming,
                                  2)

        # create nodeinput socket 3
        lbl = Gtk.Label.new("Input 3")
        lbl.set_xalign(0.1)
        node_socket_input = self.item_add(lbl, GtkNodes.NodeSocketIO.SINK)
        node_socket_input.connect("socket_incoming", self.node_socket_incoming,
                                  3)

        f = Figure(figsize=(5, 4), dpi=100)
        self.a = f.add_subplot(111)

        sw = Gtk.ScrolledWindow()
        sw.set_border_width(10)

        self.canvas = FigureCanvas(f)
        sw.add(self.canvas)
        sw.set_size_request(200, 200)

        self.item_add(sw, GtkNodes.NodeSocketIO.DISABLE)
        self.set_child_packing(sw, True, True, 0, Gtk.PackType.START)

    def plot(self, combobox):

        x = np.linspace(self.val_1, self.val_2, self.val_3)
        y = np.cos(x**2 / 3 + 4)

        tck, u = interpolate.splprep(np.array((x, y)), s=0)
        unew = np.arange(0, 1.01, 0.01)
        out = interpolate.splev(unew, tck)

        self.a.clear()

        self.a.plot(out[0], out[1], color='orange')
        self.a.plot(x, y, 'o')
        self.canvas.draw()

    def node_socket_incoming(self, socket, payload, datasource):

        x = struct.Struct("d")

        val = x.unpack(payload)[0]

        if datasource == 1:
            self.val_1 = int(val)
        elif datasource == 2:
            self.val_2 = int(val)
        elif datasource == 3:
            if (val > 10):
                self.val_3 = int(val)

        self.plot(self)

    def remove(self, node):
        self.destroy()
示例#20
0
文件: img.py 项目: ke8ctn/gtknodes
class ImgSrcNode(GtkNodes.Node):
    __gtype_name__ = 'SrcNode'

    def __init__(self, *args, **kwds):
        super().__init__(*args, **kwds)

        self.set_label("Image Source")
        self.connect("node_func_clicked", self.remove)

        self.img = misc.face()

        f = Figure(figsize=(5, 4), dpi=100)
        self.a = f.add_subplot(111)

        sw = Gtk.ScrolledWindow()
        sw.set_border_width(10)

        self.canvas = FigureCanvas(f)
        sw.add(self.canvas)
        sw.set_size_request(200, 200)

        self.item_add(sw, GtkNodes.NodeSocketIO.DISABLE)
        self.set_child_packing(sw, True, True, 0, Gtk.PackType.START)

        self.draw_image()

        # create local node settings
        sources = ["face", "ascent"]
        self.combobox = Gtk.ComboBoxText()
        self.combobox.set_entry_text_column(0)
        for src in sources:
            self.combobox.append_text(src)
        self.combobox.set_active(0)
        self.combobox.connect("changed", self.change_image)

        # internal node items are type DISABLE
        self.item_add(self.combobox, GtkNodes.NodeSocketIO.DISABLE)

        # create node output socket
        lbl = Gtk.Label.new("Image")
        lbl.set_xalign(1.0)
        self.node_socket_output = self.item_add(lbl,
                                                GtkNodes.NodeSocketIO.SOURCE)
        self.node_socket_output.connect("socket_connect",
                                        self.node_socket_connect)

        # the compatibility key
        self.node_socket_output.set_key(1234)
        self.node_socket_output.set_rgba(get_rgba('darkturquoise'))

    def draw_image(self):

        self.a.imshow(self.img)
        self.canvas.draw()

    def change_image(self, combobox):
        src = self.combobox.get_active_text()

        if src == "face":
            self.img = misc.face()
        elif src == "ascent":
            self.img = misc.ascent()

        self.draw_image()
        self.node_socket_output.write(pickle.dumps(self.img))

    def node_socket_connect(self, sink, source):
        self.node_socket_output.write(pickle.dumps(self.img))

    def remove(self, node):
        self.destroy()
示例#21
0
class GraphView():
    """Class for displaying graph"""
    def __init__(self,
                 box,
                 xlim,
                 ylim,
                 title='',
                 xlabel='',
                 ylabel='',
                 inactivate=False):

        self.box = box
        self.xlim = xlim
        self.ylim = ylim
        self.title = title
        self.xlabel = xlabel
        self.ylabel = ylabel
        self.inactivate = inactivate
        self.models = []
        self.model = None
        self.colors = ('r', 'b', 'g', 'c', 'm', 'y', 'k', 'w')
        self.signal1_id = None
        self.signal2_id = None

        self.vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.hbox_int = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
        self.scrolled_window = Gtk.ScrolledWindow()
        self.figure = Figure(figsize=(1, 1))
        self.canvas = FigureCanvas(self.figure)  # a Gtk.DrawingArea
        self.box.set_size_request(100, 300)
        self.name_widget = Gtk.Label('<i>' + self.title + '</i>', xalign=0.5)
        self.name_widget.set_use_markup(True)
        self.name_widget.props.margin_top = 6
        self.name_widget.props.margin_bottom = 6
        self.xlabel_widget = Gtk.Label('<i>' + self.xlabel + '</i>',
                                       xalign=0.5)
        self.xlabel_widget.set_use_markup(True)
        self.ylabel_widget = Gtk.Label('<i>' + self.ylabel + '</i>',
                                       xalign=0.5)
        self.ylabel_widget.set_use_markup(True)
        self.ylabel_widget.set_angle(90)
        self.box.pack_start(self.vbox, True, True, 0)
        if title:
            self.vbox.pack_start(self.name_widget, False, False, 0)
        if ylabel:
            self.hbox_int.pack_start(self.ylabel_widget, False, False, 0)
        self.hbox_int.pack_start(self.scrolled_window, True, True, 0)
        self.vbox.pack_start(self.hbox_int, True, True, 0)
        if xlabel:
            self.vbox.pack_start(self.xlabel_widget, False, False, 0)
        self.scrolled_window.add(self.canvas)
        self.plot = self.figure.add_subplot(111)
        self.plot_curves()

    # Functions

    def add_plot(self, graph_model):
        self.models.append(GraphModel(graph_model))
        if len(self.models) == 1:
            self.model = self.models[0]
        self.plot_curves()

    def add_plots(self, graph_models):
        for model in graph_models:
            self.add_plot(model)

    def clear_plots(self):
        self.models.clear()
        self.model = None

    def set_active_model(self, index):
        if index < len(self.models):
            self.model = self.models[index]

    def cycle_active_graph(self):
        index = self.models.index(self.model)
        if index < len(self.models) - 1:
            self.model = self.models[index + 1]
        else:
            self.model = self.models[0]

    def plot_curves(self):
        if self.inactivate == False:
            self.signal1_id = self.box.connect('button_press_event',
                                               self.on_click_box)
            self.signal2_id = self.canvas.mpl_connect('button_press_event',
                                                      self.on_click)
        else:
            if self.signal1_id:
                self.box.disconnect(self.signal1_id)
                self.signal1_id = None
            if self.signal2_id:
                self.canvas.mpl_disconnect(self.signal2_id)
                self.signal2_id = None

        self.plot.clear()
        for tick in self.plot.get_xticklabels():
            tick.set_fontname(misc.GRAPH_FONT_FACE)
            tick.set_fontsize(misc.GRAPH_FONT_SIZE)
        for tick in self.plot.get_yticklabels():
            tick.set_fontname(misc.GRAPH_FONT_FACE)
            tick.set_fontsize(misc.GRAPH_FONT_SIZE)
        self.plot.set_xlim(self.xlim[0], self.xlim[1])
        if len(self.xlim) == 4 and self.xlim[3] == 'log':
            self.plot.set_xscale('log')
        self.plot.set_ylim(self.ylim[0], self.ylim[1])
        self.plot.grid(True, which='major')
        self.plot.minorticks_on()
        self.plot.grid(True, which='minor', alpha=0.2)
        for slno, model in enumerate(self.models):
            color = self.colors[slno % len(self.colors)]
            self.plot.plot(model.xval, model.yval, marker="o", color=color)
        self.canvas.draw()

    # Callbacks

    def on_click_box(self, widget, event):
        self.canvas.grab_focus()

    def on_click(self, event):
        if self.model and event.xdata and event.ydata:
            x = round(event.xdata / self.xlim[2], 0) * self.xlim[2]
            y = round(event.ydata / self.ylim[2], 0) * self.ylim[2]
            if event.button == MouseButtons.LEFT_BUTTON:
                self.model.add_point(x, y)
            elif event.button == MouseButtons.MIDDLE_BUTTON:
                self.cycle_active_graph()
            else:
                self.model.remove_point(x, y)
            self.plot_curves()
示例#22
0
class GraphsView(View['GraphsPresenter', Gtk.Widget]):
    def _do_init(self) -> Gtk.Widget:
        self._widget = Gtk.Stack(margin=5)

        self._waiting_placeholder = Gtk.Label()
        self._waiting_placeholder.set_markup('<b>No data</b>')
        self._widget.add(self._waiting_placeholder)

        figure = Figure(tight_layout=True)

        self._figure_canvas = FigureCanvas(figure)
        self._figure_canvas.props.hexpand = True
        self._figure_canvas.props.vexpand = True
        self._widget.add(self._figure_canvas)

        self._ift_axes = figure.add_subplot(3, 1, 1)
        self._ift_axes.set_ylabel('IFT (mN/m)')
        volume_axes = figure.add_subplot(3, 1, 2, sharex=self._ift_axes)
        volume_axes.xaxis.set_ticks_position('both')
        volume_axes.set_ylabel('Vol. (mm³)')
        surface_area_axes = figure.add_subplot(3, 1, 3, sharex=self._ift_axes)
        surface_area_axes.xaxis.set_ticks_position('both')
        surface_area_axes.set_ylabel('Sur. (mm²)')

        # Format the labels to scale to the right units.
        self._ift_axes.get_yaxis().set_major_formatter(
            ticker.FuncFormatter(lambda x, pos: '{:.4g}'.format(x * 1e3)))
        volume_axes.get_yaxis().set_major_formatter(
            ticker.FuncFormatter(lambda x, pos: '{:.4g}'.format(x * 1e9)))
        surface_area_axes.get_yaxis().set_major_formatter(
            ticker.FuncFormatter(lambda x, pos: '{:.4g}'.format(x * 1e6)))

        for lbl in (*self._ift_axes.get_xticklabels(),
                    *volume_axes.get_xticklabels()):
            lbl.set_visible(False)

        self._ift_line = self._ift_axes.plot([], marker='o', color='red')[0]
        self._volume_line = volume_axes.plot([], marker='o', color='blue')[0]
        self._surface_area_line = surface_area_axes.plot([],
                                                         marker='o',
                                                         color='green')[0]

        self._widget.show_all()

        self.presenter.view_ready()

        return self._widget

    def show_waiting_placeholder(self) -> None:
        self._widget.set_visible_child(self._waiting_placeholder)

    def hide_waiting_placeholder(self) -> None:
        self._widget.set_visible_child(self._figure_canvas)

    def set_ift_data(self, data: Sequence[Tuple[float, float]]) -> None:
        if len(data[0]) <= 1:
            return

        self._ift_line.set_data(data)

        self._update_xlim()

        self._ift_axes.relim()
        self._ift_axes.margins(y=0.1)

        self._figure_canvas.draw()

    def set_volume_data(self, data: Sequence[Tuple[float, float]]) -> None:
        if len(data[0]) <= 1:
            return

        self._volume_line.set_data(data)

        self._update_xlim()

        self._volume_line.axes.relim()
        self._volume_line.axes.margins(y=0.1)

        self._figure_canvas.draw()

    def set_surface_area_data(self, data: Sequence[Tuple[float,
                                                         float]]) -> None:
        if len(data[0]) <= 1:
            return

        self._surface_area_line.set_data(data)

        self._update_xlim()

        self._surface_area_line.axes.relim()
        self._surface_area_line.axes.margins(y=0.1)

        self._figure_canvas.draw()

    def _update_xlim(self) -> None:
        all_xdata = (
            *self._ift_line.get_xdata(),
            *self._volume_line.get_xdata(),
            *self._surface_area_line.get_xdata(),
        )

        if len(all_xdata) <= 1:
            return

        xmin = min(all_xdata)
        xmax = max(all_xdata)

        if xmin == xmax:
            return

        self._ift_axes.set_xlim(xmin, xmax)

    def _do_destroy(self) -> None:
        self._widget.destroy()
class EditFanProfileView(EditFanProfileViewInterface):
    @inject
    def __init__(self,
                 presenter: EditFanProfilePresenter,
                 builder: EditFanProfileBuilder,
                 ) -> None:
        LOG.debug('init EditFanProfileView')
        self._presenter: EditFanProfilePresenter = presenter
        self._presenter.view = self
        self._builder: Gtk.Builder = builder
        self._builder.connect_signals(self._presenter)
        self._init_widgets()

    def _init_widgets(self) -> None:
        self._dialog: Gtk.Dialog = self._builder.get_object('dialog')
        self._delete_profile_button: Gtk.Button = self._builder \
            .get_object('delete_profile_button')
        self._profile_name_entry: Gtk.Entry = self._builder \
            .get_object('profile_name_entry')
        self._liststore: Gtk.ListStore = self._builder.get_object('liststore')
        self._temperature_adjustment: Gtk.Adjustment = self._builder \
            .get_object('temperature_adjustment')
        self._duty_adjustment: Gtk.Adjustment = self._builder \
            .get_object('duty_adjustment')
        self._temperature_scale: Gtk.Scale = self._builder \
            .get_object('temperature_scale')
        self._duty_scale: Gtk.Scale = self._builder \
            .get_object('duty_scale')
        self._controls_grid: Gtk.Grid = self._builder.get_object('controls_grid')
        self._treeselection: Gtk.TreeSelection = self._builder.get_object('treeselection')
        self._treeview: Gtk.TreeView = self._builder.get_object('treeview')
        self._add_step_button: Gtk.Button = self._builder.get_object('add_step_button')
        self._save_step_button: Gtk.Button = self._builder \
            .get_object('save_step_button')
        self._delete_step_button: Gtk.Button = self._builder \
            .get_object('delete_step_button')
        self._init_plot_charts()

    def set_transient_for(self, window: Gtk.Window) -> None:
        self._dialog.set_transient_for(window)

    # pylint: disable=attribute-defined-outside-init
    def _init_plot_charts(self, ) -> None:
        self._chart_figure = Figure(figsize=(8, 6), dpi=72, facecolor='#00000000')
        self._chart_canvas = FigureCanvas(self._chart_figure)  # a Gtk.DrawingArea+
        self._chart_axis = self._chart_figure.add_subplot(111)
        self._chart_line, = init_plot_chart(
            self._builder.get_object('scrolled_window'),
            self._chart_figure,
            self._chart_canvas,
            self._chart_axis
        )

    def _plot_chart(self, data: Dict[int, int]) -> None:
        sorted_data = OrderedDict(sorted(data.items()))
        temperature = list(sorted_data.keys())
        duty = list(sorted_data.values())
        self._chart_line.set_xdata(temperature)
        self._chart_line.set_ydata(duty)
        self._chart_canvas.draw()
        self._chart_canvas.flush_events()

    def show(self, profile: FanProfile) -> None:
        self._treeselection.unselect_all()
        self._profile_name_entry.set_text(profile.name)
        self.refresh_liststore(profile)
        self.refresh_controls()
        self._dialog.show_all()

    def hide(self) -> None:
        self._dialog.hide()

    def get_profile_name(self) -> str:
        return str(self._profile_name_entry.get_text())

    def get_temperature(self) -> int:
        return int(self._temperature_adjustment.get_value())

    def get_duty(self) -> int:
        return int(self._duty_adjustment.get_value())

    def has_a_step_selected(self) -> bool:
        return self._treeselection.get_selected()[1] is not None

    def refresh_liststore(self, profile: FanProfile) -> None:
        self._liststore.clear()
        for step in profile.steps:
            self._liststore.append([step.id, step.temperature, step.duty])
        if profile.steps:
            if profile.steps[-1].temperature == MAX_TEMP or profile.steps[-1].duty == FAN_MAX_DUTY:
                self._add_step_button.set_sensitive(False)
            else:
                self._add_step_button.set_sensitive(True)
        else:
            self._add_step_button.set_sensitive(True)

        self._plot_chart(get_fan_profile_data(profile))

    def refresh_controls(self, step: Optional[SpeedStep] = None, unselect_list: bool = False) -> None:
        if unselect_list:
            self._treeselection.unselect_all()
        if step is None:
            self._controls_grid.set_sensitive(False)
        else:
            prev_steps = (SpeedStep
                          .select()
                          .where(SpeedStep.profile == step.profile, SpeedStep.temperature < step.temperature)
                          .order_by(SpeedStep.temperature.desc())
                          .limit(1))
            next_steps = (SpeedStep
                          .select()
                          .where(SpeedStep.profile == step.profile, SpeedStep.temperature > step.temperature)
                          .order_by(SpeedStep.temperature)
                          .limit(1))
            if not prev_steps:
                self._temperature_adjustment.set_lower(MIN_TEMP)
                self._duty_adjustment.set_lower(FAN_MIN_DUTY)
            else:
                LOG.debug(f"prev = {prev_steps[0].temperature}")
                self._temperature_adjustment.set_lower(prev_steps[0].temperature + 1)
                self._duty_adjustment.set_lower(prev_steps[0].duty)

            if not next_steps:
                self._temperature_adjustment.set_upper(MAX_TEMP)
                self._duty_adjustment.set_upper(FAN_MAX_DUTY)
            else:
                self._temperature_adjustment.set_upper(next_steps[0].temperature - 1)
                self._duty_adjustment.set_upper(next_steps[0].duty)

            self._controls_grid.set_sensitive(True)
            self._temperature_scale.clear_marks()
            self._temperature_scale.add_mark(step.temperature, Gtk.PositionType.BOTTOM)
            self._temperature_adjustment.set_value(step.temperature)
            self._duty_scale.clear_marks()
            self._duty_scale.add_mark(step.duty, Gtk.PositionType.BOTTOM)
            self._duty_adjustment.set_value(step.duty)
示例#24
0
class plotwidget(object):
    def __init__(self, data_queue):
        self.plottype = 'normal'
        self.fig = Figure(figsize=(5, 5), dpi=100)
        self.ax = self.fig.add_subplot(111, aspect='equal')
        self.ax.set_xlabel('X', size=12)
        self.ax.set_ylabel('Y', size=12)
        #self.ax.yaxis.set_label_coords()
        self.fig.subplots_adjust(left=0.15, top=0.85)
        self.ax.axis([0, 255, 0, 255])
        self.x_vals = np.empty(0, np.uint16)
        self.y_vals = np.empty(0, np.uint16)
        self.t_vals = np.empty(0, np.uint16)
        self.intensity = np.empty(0, np.uint16)
        self.length = np.empty(0, np.uint16)
        self.i = 0
        self.occupancy_array = np.array([[0, 0, 0]])
        self.occ_length = []
        self.j = 0
        self.old_elements = np.array([[0, 0]])
        self.occupancy = []
        self.integration_length = 500
        self.color_depth = 10
        cmap = self.fading_colormap(5)
        self.data_queue = data_queue

        self.scatter = self.ax.scatter(self.x_vals,
                                       self.y_vals,
                                       c=[],
                                       s=1,
                                       marker='s',
                                       cmap=cmap,
                                       vmin=0,
                                       vmax=1)

        self.canvas = FigureCanvas(self.fig)
        self.canvas.set_size_request(500, 500)

        self.ax.plot()

    def fading_colormap(self, steps=5):
        # This creates a fading colormap of 'steps' steps. Each step is more transparent,
        #  so if plotted correctly the data appers to be fading out.
        if steps <= 0:
            self.colorsteps = 1
            print(
                'ERROR: Minimum number of colorsteps is 1. Colorsteps have been set to 1.'
            )
        else:
            self.colorsteps = steps

        i = 1
        viridis = cm.get_cmap('viridis', 256)
        newcmap = viridis(np.linspace(0, 1, 256))
        newmap1 = np.tile(newcmap, (self.colorsteps, 1))
        while (i < self.colorsteps):
            newmap1[(i - 1) * 256:(i * 256),
                    -1] = np.linspace(i * 1 / self.colorsteps,
                                      i * 1 / self.colorsteps, 256)
            i = i + 1
        cmap = ListedColormap(newmap1)

        return cmap

    def get_new_vals(self):
        #Get values from Chip
        #t need to between 0 and 1 then the calculation 1 - (t / self.colorsteps) needs
        #to be done in order to distribute is correctly over the colormap
        x = np.empty(0, np.uint16)
        y = np.empty(0, np.uint16)
        t = np.empty(0, np.uint16)

        if not self.data_queue.empty():
            x_new, y_new, t_new = self.data_queue.get()
            x = np.append(x, x_new)
            y = np.append(y, y_new)
            t = np.append(t, t_new)
        if len(t) > 0:
            self.t_vals = np.append(self.t_vals, t)
            max_value = np.amax(
                self.t_vals)  # This has to be changed to a more general way
            t = t / max_value

        return x, y, t

    def update_plot(self):
        #Plot the fading plot with new data.
        new_xvals, new_yvals, new_tvals = self.get_new_vals()
        self.x_vals = np.append(self.x_vals, new_xvals)
        self.y_vals = np.append(self.y_vals, new_yvals)
        self.length = np.append(self.length, new_xvals.size)

        #Cut plotting arrays to n_colorsteps Timeblocks
        if self.i < (self.colorsteps):
            self.i = self.i + 1

        elif self.i == (self.colorsteps):
            number = np.arange(self.length[0])
            self.length = np.delete(self.length, 0)
            self.x_vals = np.delete(self.x_vals, number)
            self.y_vals = np.delete(self.y_vals, number)
            self.t_vals = np.delete(self.t_vals, number)
            self.intensity = np.delete(self.intensity, number)

        elif self.i > (self.colorsteps):
            while self.i >= (self.colorsteps):
                number = np.arange(self.length[0])
                self.length = np.delete(self.length, 0)
                self.x_vals = np.delete(self.x_vals, number)
                self.y_vals = np.delete(self.y_vals, number)
                self.t_vals = np.delete(self.t_vals, number)
                self.intensity = np.delete(self.intensity, number)
                self.i = self.i - 1

        #Add to plot and change intensity
        self.scatter.set_offsets(np.c_[self.x_vals, self.y_vals])
        self.intensity = np.concatenate(
            (np.array(self.intensity) - (1 / self.colorsteps), new_tvals))

        self.scatter.set_array(self.intensity)

        self.canvas.draw()

        return True

    def update_occupancy_plot(self):
        new_xvals, new_yvals, new_tvals = self.get_new_vals()
        new_elements = np.c_[new_xvals, new_yvals]
        self.occ_length.append(new_elements.shape[0])
        self.old_elements = np.append(self.old_elements, new_elements, axis=0)

        #count hited pixel
        for new_element in new_elements:
            pos = np.argwhere(
                np.all(self.occupancy_array[:, :2] == new_element, axis=1) ==
                True)
            if pos.size == 0:
                # add new element
                self.occupancy_array = np.append(self.occupancy_array,
                                                 [np.append(new_element, 1)],
                                                 axis=0)

            elif pos.size == 1:
                #increment element at pos
                x = pos[0, 0]
                self.occupancy_array[pos[0, 0],
                                     2] = (self.occupancy_array[pos[0, 0], 2] +
                                           1)

            else:
                print('Error')

        #remove hitted pixel
        if self.j <= (self.integration_length):
            self.j = self.j + 1

        elif self.j == (self.integration_length + 1):
            number = self.occ_length[0]
            self.occ_length.pop(0)
            k = 0
            while k < number:
                k = k + 1
                pos = np.argwhere(
                    np.all(self.occupancy_array[:, :2] == self.old_elements[1],
                           axis=1) == True)
                self.old_elements = np.delete(self.old_elements, 1, axis=0)
                if self.occupancy_array[pos[0, 0], 2] == 1:
                    #Remove item if no count left
                    self.occupancy_array = np.delete(self.occupancy_array,
                                                     pos[0, 0],
                                                     axis=0)

                elif self.occupancy_array[pos[0, 0], 2] > 1:
                    #decrement element at pos
                    self.occupancy_array[pos[0, 0], 2] = (
                        self.occupancy_array[pos[0, 0], 2] - 1)

                else:
                    print('Error')

        elif self.j > (self.integration_length + 1):
            while self.j > (self.integration_length + 1):
                number = self.occ_length[0]
                self.occ_length.pop(0)
                k = 0
                while k < number:
                    k = k + 1
                    pos = np.argwhere(
                        np.all(self.occupancy_array[:, :2] ==
                               self.old_elements[1],
                               axis=1) == True)
                    self.old_elements = np.delete(self.old_elements, 1, axis=0)
                    if self.occupancy_array[pos[0, 0], 2] == 1:
                        #Remove item if no count left
                        self.occupancy_array = np.delete(self.occupancy_array,
                                                         pos[0, 0],
                                                         axis=0)

                    elif self.occupancy_array[pos[0, 0], 2] > 1:
                        #Decrement element at pos
                        self.occupancy_array[pos[0, 0], 2] = (
                            self.occupancy_array[pos[0, 0], 2] - 1)

                    else:
                        print('Error')

                self.j = self.j - 1

        self.scatter.set_offsets(self.occupancy_array[:, :2])
        self.occupancy = self.occupancy_array[:, 2:]
        self.scatter.set_array(np.squeeze(self.occupancy))
        self.canvas.draw()

        return True

    def reset_occupancy(self):
        self.occupancy_array = np.array([[0, 0, 0]])
        self.occ_length = []
        self.j = 0
        self.old_elements = np.array([[0, 0]])
        self.occupancy = []

        return True

    def change_colormap(self, colormap, vmin=0, vmax=1):
        x_vals = []
        y_vals = []
        cmap = colormap
        vmin = vmin
        vmax = vmax
        if self.plottype == 'occupancy':
            self.color_depth = vmax

        self.ax.remove()
        self.ax = self.fig.add_subplot(111, aspect='equal')
        self.ax.set_xlabel('X', size=12)
        self.ax.set_ylabel('Y', size=12)
        self.ax.axis([0, 255, 0, 255])
        self.scatter = self.ax.scatter(x_vals,
                                       y_vals,
                                       c=[],
                                       s=1,
                                       marker='s',
                                       cmap=cmap,
                                       vmin=vmin,
                                       vmax=vmax)
        self.ax.plot()

        return True

    def get_iteration_depth(self, function='normal'):
        function = function
        if function == 'normal':
            return self.colorsteps

        elif function == 'occupancy':
            return self.integration_length

        elif function == 'occupancy.color':
            return self.color_depth

        else:
            print(
                'Unknown argument. Use "normal", "occupancy" or "occupancy.color'
            )
            return False

    def get_plottype(self):
        return self.plottype

    def set_plottype(self, plottype):
        self.plottype = plottype
        return True

    def set_occupancy_length(self, length):
        self.integration_length = length
        return True

    def set_color_depth(self, color_depth):
        self.color_depth = color_depth
        return True

    def set_color_steps(self, color_steps):
        self.colorsteps = color_steps
        return True
示例#25
0
class myInterface():

    def __init__(self, port, baud):
        print("Welcome to the MakeMeFly interface :D\nEnjoy your trip!")

        self.port=port
        self.baud=baud
        self.s=Serial(self.port, self.baud, timeout=0.5)
        self.inhibited=False;

        self.dataLock=Lock()
        self.printDataLock=Lock()
        self.bufLock=Lock()
        self.serialLock=Lock()
        self.saveStuffLock=Lock()
        self.buf=[]

        self.builder=Gtk.Builder()
        self.builder.add_from_file('Plotter_IF.glade')
        self.builder.connect_signals(self)

        self.squareWave=[]
        self.outputUp=[]
        self.outputDown=[]
        self.sw=0
        self.co=0
        self.ou=0
        self.od=0
        self.gb=0
        self.gp=0
        self.ur=0
        self.dr=0
        self.bM=0
        self.bm=0
        self.l=[]

        self.gainBase=[]
        self.gainPos=[]
        self.upRate=[]
        self.downRate=[]
        self.BMax=0
        self.BMin=0
        self.level=[]

        self.nData=1000
        self.BData=deque(maxlen=1000)
        self.filteredValueData=deque(maxlen=1000)
        self.coilBData=deque(maxlen=1000)
        self.BData.append(0)
        self.filteredValueData.append(0)
        self.coilBData.append(0)
        self.XData=[0.0004*x for x in range(0,1000)]

        self.window=self.builder.get_object("mainWindow")
        self.builder.get_object("sqWaveImage").set_from_stock("gtk-no", Gtk.IconSize.BUTTON)

        #Start of Matplotlib specific code
        ##########################################################################
        self.figure = Figure(figsize=(8,6), dpi=71)
        self.axisB = self.figure.add_subplot(311)
        self.axisB.set_xlabel('Time (ticks)')
        self.axisB.set_ylabel('Measured magnetic field')

        self.axisBC = self.figure.add_subplot(313)
        self.axisBC.set_xlabel('Time (ticks)')
        self.axisBC.set_ylabel('Emulated magnetic field')

        self.axisFV = self.figure.add_subplot(312)
        self.axisFV.set_xlabel('Time (ticks)')
        self.axisFV.set_ylabel('Filtered magnetic field')

        self.plotCanvas = PlotCanvas(self.figure)  # a Gtk.DrawingArea
        self.plotCanvas.set_size_request(500,600)
        a=[0]
        self.plotB=self.axisB.plot(a)[0]
        self.plotBC=self.axisBC.plot(a)[0]
        self.plotFV=self.axisFV.plot(a)[0]
        self.plotCanvas.draw()

        self.builder.get_object("plotGrid").attach(self.plotCanvas, 0,2,1,1)
        self.window.show_all()
        self.window.connect("destroy", Gtk.main_quit)

        self.newBytes=Condition()
        self.recvThread=Thread(target=self.recvBytes)
        self.recvThread.start()
        self.consumeDataThread=Thread(target=self.consumeData)
        self.consumeDataThread.start()

    def getNext(self, requested):
        while(len(self.buf)<requested):
            self.newBytes.acquire()
            self.newBytes.wait()
            self.newBytes.release()
        self.bufLock.acquire()
        values=self.buf[:requested]
        self.buf=self.buf[requested:]
        self.bufLock.release()
        return values

    def updateIF(self, a,b):
            self.dataLock.acquire()
            sw=self.sw
            ou=self.ou
            od=self.od
            co=self.co
            gb=self.gb
            gp=self.gp
            ur=self.ur
            dr=self.dr
            bmax=self.bM
            bmin=self.bm
            l=self.l
            self.dataLock.release()

            if(gb!=self.gainBase):
                self.gainBase=gb
                self.builder.get_object("gainBaseLabel").set_label("Base power: "+str(self.gainBase))
            if(gp!=self.gainPos):
                self.gainPos=gp
                self.builder.get_object("gainPosLabel").set_label("Position gain: "+str(self.gainPos))
            if(ur!=self.upRate):
                self.upRate=ur
                self.builder.get_object("upRateLabel").set_label("Charging step: "+str(self.upRate))
            if(bmax!=self.BMax):
                self.BMax=bmax
                self.builder.get_object("BMaxLabel").set_label("ON field: "+str(self.BMax))
            if(bmin!=self.BMin):
                self.BMin=bmin
                self.builder.get_object("BMinLabel").set_label("Base field: "+str(self.BMin))
            if(dr!=self.downRate):
                self.downRate=dr
                self.builder.get_object("downRateLabel").set_label("Discharging step: "+str(self.downRate))
            if(l!=self.level):
                self.level=l
                self.builder.get_object("levelLabel").set_label("Level: "+str(self.level))
            if(sw!=self.squareWave):
                self.squareWave=sw
                if(sw):
                    self.builder.get_object("sqWaveImage").set_from_stock("gtk-yes", Gtk.IconSize.BUTTON)
                    self.builder.get_object("sqWaveLabel").set_label("SquareWave: ON")
                else:
                    self.builder.get_object("sqWaveImage").set_from_stock("gtk-no", Gtk.IconSize.BUTTON)
                    self.builder.get_object("sqWaveLabel").set_label("SquareWave: OFF")

            if(ou!=self.outputUp):
                self.outputUp=ou
                if(ou):
                    self.builder.get_object("outputUpImage").set_from_stock("gtk-yes", Gtk.IconSize.BUTTON)
                    self.builder.get_object("outputUpLabel").set_label("Output up: ON")
                else:
                    self.builder.get_object("outputUpImage").set_from_stock("gtk-no", Gtk.IconSize.BUTTON)
                    self.builder.get_object("outputUpLabel").set_label("Output up: OFF")

            if(od!=self.outputDown):
                self.outputDown=od
                if(od):
                    self.builder.get_object("outputDownImage").set_from_stock("gtk-yes", Gtk.IconSize.BUTTON)
                    self.builder.get_object("outputDownLabel").set_label("Output down: ON")
                else:
                    self.builder.get_object("outputDownImage").set_from_stock("gtk-no", Gtk.IconSize.BUTTON)
                    self.builder.get_object("outputDownLabel").set_label("Output down: OFF")
            if(od!=self.outputDown):
                self.outputDown=od
                if(od):
                    self.builder.get_object("outputDownImage").set_from_stock("gtk-yes", Gtk.IconSize.BUTTON)
                    self.builder.get_object("outputDownLabel").set_label("Output down: ON")
                else:
                    self.builder.get_object("outputDownImage").set_from_stock("gtk-no", Gtk.IconSize.BUTTON)
                    self.builder.get_object("outputDownLabel").set_label("Output down: OFF")
            self.printDataLock.acquire()
#Note for the reader: 
#While I was writing this code, a thief came into my house and tried stealing my car; I bravely run to him shouting and made him run away. Don't expect this code to be clean anymore.
# (True story!)
            self.axisB.set_xbound(lower=0,upper=len(self.BData))
            self.axisB.set_ybound(lower=min(self.BData), upper=len(self.BData))
            self.plotB.set_xdata(np.arange(len(self.BData)))
            self.plotB.set_ydata(np.array(self.BData))
            #self.plotB.set_xdata(self.XData[:n])
            #self.plotB.set_ydata(self.BData)

            self.axisBC.set_xbound(lower=0,upper=len(self.coilBData))
            self.axisBC.set_ybound(lower=min(self.coilBData), upper=len(self.coilBData))
            self.plotBC.set_xdata(np.arange(len(self.coilBData)))
            self.plotBC.set_ydata(np.array(self.coilBData))

            self.axisFV.set_xbound(lower=0,upper=len(self.filteredValueData))
            self.axisFV.set_ybound(lower=min(self.filteredValueData), upper=len(self.filteredValueData))
            self.plotFV.set_xdata(np.arange(len(self.filteredValueData)))
            self.plotFV.set_ydata(np.array(self.filteredValueData))
            self.plotCanvas.draw()
            self.printDataLock.release()

    def consumeData(self):
        while(not self.inhibited):
#Waits for sync
            while(True):
                if(self.getNext(1)==[0x4C]):
                    if(self.getNext(1)==[0x56]):
                        if(self.getNext(1)==[0x54]):
                            break
            data=self.getNext(14)
            self.dataLock.acquire()
            self.l=int(data[0])*16;
            self.gp=float(data[2]*256+data[1]+(-65536 if data[2] & 0x80 else 0))/10000.0
            self.gb=float(data[4]*256+data[3]+(-65536 if data[4] & 0x80 else 0))/1000.0+1
            self.ur=float(data[6]*256+data[5]+(-65536 if data[6] & 0x80 else 0))/10000.0
            self.dr=float(data[8]*256+data[7]+(-65536 if data[8] & 0x80 else 0))/10000.0
            self.bM=(data[10]*256+data[9])
            self.bm=(data[12]*256+data[11])
            state=data[13]
            self.sw=state & 0x01
            self.ou=state & 0x02
            self.od=state & 0x04
            self.co=state & 0x08
            self.dataLock.release()
            if((self.ou and self.co) or (self.od and not self.co)):
                values=self.getNext(6)
                filteredValue=float(values[1]*256+data[0]+(-65536 if data[1] & 0x80 else 0))/256.0
                coilB=float(values[3]*256+data[2]+(-65536 if data[1] & 0x80 else 0))/256.0
                B=float(values[5]*256+data[4]+(-65536 if data[1] & 0x80 else 0))/256.0
                #print(str(filteredValue)+" "+str(coilB)+" "+str(B))
                self.printDataLock.acquire()
                self.BData.append(B)
                self.coilBData.append(coilB)
                self.filteredValueData.append(filteredValue)
                self.printDataLock.release()

    def recvBytes(self):
        self.s.flushInput()
        a=[x for x in range(256)]
        while(True):
            n=self.s.readinto(a)
            self.bufLock.acquire()
            self.buf.extend(a[:n])
            if(len(self.buf)>1000):
                self.buf=self.buf[-500:]
            self.bufLock.release()
            self.newBytes.acquire()
            self.newBytes.notify()
            self.newBytes.release()


    def updateNData(self,a):
        value=int(self.builder.get_object("nDataInput").get_text())
        print("New data: " + str(value))
        if(value>65536 or value<0):
            print("Invalid value")
        else:
            if(value!=self.nData):
                self.nData=value
                self.printDataLock.acquire()
                bd=self.BData
                fd=self.filteredValueData
                cbd=self.coilBData
                self.XData=[0.0004*x for x in range(0,value)]
                self.axisB.set_xbound(lower=self.XData[0], upper=self.XData[-1])
                self.BData=deque(maxlen=value)
                self.BData.extend(bd)
                self.filteredValueData=deque(maxlen=value)
                self.filteredValueData.extend(fd)
                self.coilBData=deque(maxlen=value)
                self.coilBData.extend(cbd)
                self.printDataLock.release()

    def changeSquareWave(self,a):
        print("SquareWave change")
        self.serialLock.acquire()
        self.s.write([ord('s') ,0x0A,0x0D])
        self.s.flush()
        self.serialLock.release()

    def changeOutputUp(self,a):
        print("Change output up")
        self.serialLock.acquire()
        self.s.write([ord('O'),0x0A,0x0D])
        self.s.flush()
        self.serialLock.release()

    def changeOutputDown(self,a):
        print("Change output down")
        self.serialLock.acquire()
        self.s.write([ord('o') ,0x0A,0x0D])
        self.s.flush()
        self.serialLock.release()

    def gainBaseUp(self,a):
        print("Gain base up")
        self.serialLock.acquire()
        self.s.write([ord('P') ,0x0A,0x0D])
        self.s.flush()
        self.serialLock.release()

    def gainBaseDown(self,a):
        print("Gain base down")
        self.serialLock.acquire()
        self.s.write([ord('p') ,0x0A,0x0D])
        self.s.flush()
        self.serialLock.release()

    def gainPosUp(self,a):
        print("Gain pos up")
        self.serialLock.acquire()
        self.s.write([ord('G') ,0x0A,0x0D])
        self.s.flush()
        self.serialLock.release()

    def gainPosDown(self,a):
        print("Gain pos down")
        self.serialLock.acquire()
        self.s.write([ord('g') ,0x0A,0x0D])
        self.s.flush()
        self.serialLock.release()

    def upRateUp(self,a):
        print("Up rate up")
        self.serialLock.acquire()
        self.s.write([ord('U') ,0x0A,0x0D])
        self.s.flush()
        self.serialLock.release()

    def upRateDown(self,a):
        print("Up rate down")
        self.serialLock.acquire()
        self.s.write([ord('u') ,0x0A,0x0D])
        self.s.flush()
        self.serialLock.release()

    def downRateUp(self,a):
        print("Down rate up")
        self.serialLock.acquire()
        self.s.write([ord('D') ,0x0A,0x0D])
        self.s.flush()
        self.serialLock.release()

    def downRateDown(self,a):
        print("Down rate down")
        self.serialLock.acquire()
        self.s.write([ord('d') ,0x0A,0x0D])
        self.s.flush()
        self.serialLock.release()

    def saveStuff(self,a):
        print("Saving data to FLASH memory")
        self.inhibited=True
        self.saveStuffLock.acquire()
        self.serialLock.acquire()
        self.s.write([ord('W') ,0x0A,0x0D])
        while(True):
            if(self.getNext(1)==[ord('A')]):
                if(self.getNext(1)==[ord('C')]):
                    if(self.getNext(1)==[ord('K')]):
                        break
        print("Success!")
        self.inhibited=False
        self.serialLock.release()
        self.saveStuffLock.release()
示例#26
0
class MainView(MainViewInterface):
    @inject
    def __init__(
        self,
        presenter: MainPresenter,
        edit_fan_profile_view: EditFanProfileView,
        edit_overclock_profile_view: EditOverclockProfileView,
        historical_data_view: HistoricalDataView,
        preferences_view: PreferencesView,
        builder: MainBuilder,
        settings_interactor: SettingsInteractor,
    ) -> None:
        LOG.debug('init MainView')
        self._presenter: MainPresenter = presenter
        self._edit_fan_profile_view = edit_fan_profile_view
        self._edit_overclock_profile_view = edit_overclock_profile_view
        self._historical_data_view = historical_data_view
        self._preferences_view = preferences_view
        self._presenter.main_view = self
        self._builder: Gtk.Builder = builder
        self._settings_interactor = settings_interactor
        self._first_refresh = True
        self._init_widgets()

    def _init_widgets(self) -> None:
        self._app_indicator: Optional[AppIndicator3.Indicator] = None
        self._window = self._builder.get_object("application_window")
        self._edit_fan_profile_view.set_transient_for(self._window)
        self._edit_overclock_profile_view.set_transient_for(self._window)
        self._historical_data_view.set_transient_for(self._window)
        self._preferences_view.set_transient_for(self._window)
        self._main_menu: Gtk.Menu = self._builder.get_object("main_menu")
        self._main_infobar: Gtk.InfoBar = self._builder.get_object(
            "main_infobar")
        self._main_infobar.connect("response",
                                   lambda b, _: b.set_revealed(False))
        self._main_infobar_label: Gtk.Label = self._builder.get_object(
            "main_infobar_label")
        self._main_infobar.set_revealed(False)
        self._statusbar: Gtk.Statusbar = self._builder.get_object('statusbar')
        self._context = self._statusbar.get_context_id(APP_PACKAGE_NAME)
        self._app_version: Gtk.Label = self._builder.get_object('app_version')
        self._app_version.set_label(f"{APP_NAME} v{APP_VERSION}")
        self._about_dialog: Gtk.AboutDialog = self._builder.get_object(
            "about_dialog")
        self._init_about_dialog()
        self._info_name_entry: Gtk.Entry = self._builder.get_object(
            'info_name_entry')
        self._info_vbios_entry: Gtk.Entry = self._builder.get_object(
            'info_vbios_entry')
        self._info_driver_entry: Gtk.Entry = self._builder.get_object(
            'info_driver_entry')
        self._info_pcie_entry: Gtk.Entry = self._builder.get_object(
            'info_pcie_entry')
        self._info_cuda_entry: Gtk.Entry = self._builder.get_object(
            'info_cuda_entry')
        self._info_uuid_entry: Gtk.Entry = self._builder.get_object(
            'info_uuid_entry')
        self._info_memory_entry: Gtk.Entry = self._builder.get_object(
            'info_memory_entry')
        self._info_memory_interface_entry: Gtk.Entry = self._builder.get_object(
            'info_memory_interface_entry')
        self._info_memory_usage_entry: Gtk.Entry = self._builder.get_object(
            'info_memory_usage_entry')
        self._info_gpu_usage_entry: Gtk.Entry = self._builder.get_object(
            'info_gpu_usage_entry')
        self._info_encoder_usage_entry: Gtk.Entry = self._builder.get_object(
            'info_encoder_usage_entry')
        self._info_decoder_usage_entry: Gtk.Entry = self._builder.get_object(
            'info_decoder_usage_entry')
        self._power_draw_entry: Gtk.Entry = self._builder.get_object(
            'power_draw_entry')
        self._power_limit_entry: Gtk.Entry = self._builder.get_object(
            'power_limit_entry')
        self._power_default_entry: Gtk.Entry = self._builder.get_object(
            'power_default_entry')
        self._power_min_entry: Gtk.Entry = self._builder.get_object(
            'power_min_entry')
        self._power_enforced_entry: Gtk.Entry = self._builder.get_object(
            'power_enforced_entry')
        self._power_max_entry: Gtk.Entry = self._builder.get_object(
            'power_max_entry')
        self._clocks_graphics_current_entry: Gtk.Entry = self._builder.get_object(
            'clocks_graphics_current_entry')
        self._clocks_graphics_max_entry: Gtk.Entry = self._builder.get_object(
            'clocks_graphics_max_entry')
        self._clocks_sm_current_entry: Gtk.Entry = self._builder.get_object(
            'clocks_sm_current_entry')
        self._clocks_sm_max_entry: Gtk.Entry = self._builder.get_object(
            'clocks_sm_max_entry')
        self._clocks_memory_current_entry: Gtk.Entry = self._builder.get_object(
            'clocks_memory_current_entry')
        self._clocks_memory_max_entry: Gtk.Entry = self._builder.get_object(
            'clocks_memory_max_entry')
        self._clocks_video_current_entry: Gtk.Entry = self._builder.get_object(
            'clocks_video_current_entry')
        self._clocks_video_max_entry: Gtk.Entry = self._builder.get_object(
            'clocks_video_max_entry')
        self._overclock_gpu_offset_entry: Gtk.Entry = self._builder.get_object(
            'overclock_gpu_offset_entry')
        self._overclock_mem_offset_entry: Gtk.Entry = self._builder.get_object(
            'overclock_mem_offset_entry')
        self._info_memory_usage_levelbar: Gtk.LevelBar = self._builder.get_object(
            'info_memory_usage_levelbar')
        self._info_gpu_usage_levelbar: Gtk.LevelBar = self._builder.get_object(
            'info_gpu_usage_levelbar')
        self._info_encoder_usage_levelbar: Gtk.LevelBar = self._builder.get_object(
            'info_encoder_usage_levelbar')
        self._info_decoder_usage_levelbar: Gtk.LevelBar = self._builder.get_object(
            'info_decoder_usage_levelbar')
        self._temp_gpu_value: Gtk.Label = self._builder.get_object(
            'temp_gpu_value')
        self._temp_max_gpu_value: Gtk.Label = self._builder.get_object(
            'temp_max_gpu_value')
        self._temp_slowdown_value: Gtk.Label = self._builder.get_object(
            'temp_slowdown_value')
        self._temp_shutdown_value: Gtk.Label = self._builder.get_object(
            'temp_shutdown_value')
        self._fan_duty: Tuple = (self._builder.get_object('fan_duty_0'),
                                 self._builder.get_object('fan_duty_1'),
                                 self._builder.get_object('fan_duty_2'),
                                 self._builder.get_object('fan_duty_3'),
                                 self._builder.get_object('fan_duty_4'))
        self._fan_rpm: Tuple = (self._builder.get_object('fan_rpm_0'),
                                self._builder.get_object('fan_rpm_1'),
                                self._builder.get_object('fan_rpm_2'),
                                self._builder.get_object('fan_rpm_3'),
                                self._builder.get_object('fan_rpm_4'))
        self._fan_warning_label: Gtk.Label = self._builder.get_object(
            'fan_warning_label')
        self._overclock_warning_label: Gtk.Label = self._builder.get_object(
            'overclock_warning_label')
        self._fan_profile_frame: Gtk.Frame = self._builder.get_object(
            'fan_profile_frame')
        self._overclock_frame: Gtk.Frame = self._builder.get_object(
            'overclock_frame')
        self._power_limit_scale: Gtk.Scale = self._builder.get_object(
            'power_limit_scale')
        self._power_limit_adjustment: Gtk.Adjustment = self._builder.get_object(
            'power_limit_adjustment')
        self._fan_apply_button: Gtk.Button = self._builder.get_object(
            'fan_apply_button')
        self._overclock_apply_button: Gtk.Button = self._builder.get_object(
            'overclock_apply_button')
        self._power_limit_apply_button: Gtk.Button = self._builder.get_object(
            'power_limit_apply_button')
        self._fan_liststore: Gtk.ListStore = self._builder.get_object(
            'fan_profile_liststore')
        self._overclock_liststore: Gtk.ListStore = self._builder.get_object(
            'overclock_profile_liststore')
        self._fan_combobox: Gtk.ComboBox = self._builder.get_object(
            'fan_profile_combobox')
        self._overclock_combobox: Gtk.ComboBox = self._builder.get_object(
            'overclock_profile_combobox')
        fan_scrolled_window: Gtk.ScrolledWindow = self._builder.get_object(
            'fan_scrolled_window')
        self._fan_edit_button: Gtk.Button = self._builder.get_object(
            'fan_edit_button')
        self._overclock_edit_button: Gtk.Button = self._builder.get_object(
            'overclock_edit_button')
        self._init_plot_charts(fan_scrolled_window)
        if not is_dazzle_version_supported():
            self._builder.get_object("historical_data_button").set_sensitive(
                False)

    def _init_about_dialog(self) -> None:
        self._about_dialog.set_program_name(APP_NAME)
        self._about_dialog.set_version(APP_VERSION)
        self._about_dialog.set_website(APP_SOURCE_URL)
        self._about_dialog.connect("delete-event", hide_on_delete)
        self._about_dialog.connect("response", hide_on_delete)

    def show(self) -> None:
        self._presenter.on_start()
        self._init_app_indicator()

    def _init_app_indicator(self) -> None:
        if AppIndicator3:
            # Setting icon name in new() as '', because new() wants an icon path
            self._app_indicator = AppIndicator3.Indicator \
                .new(APP_ID, '', AppIndicator3.IndicatorCategory.HARDWARE)
            # Set the actual icon by name. If the app is not installed system-wide, the icon won't show up,
            # otherwise it will show up correctly. The set_icon_full() function needs a description for accessibility
            # purposes. I gave it the APP_NAME (should be 'gwe', maybe change it to 'GreenWithEnvy' in the future)
            self._app_indicator.set_icon_full(APP_ICON_NAME_SYMBOLIC, APP_NAME)
            if self._settings_interactor.get_bool(
                    'settings_show_app_indicator'):
                self._app_indicator.set_status(
                    AppIndicator3.IndicatorStatus.ACTIVE)
            else:
                self._app_indicator.set_status(
                    AppIndicator3.IndicatorStatus.PASSIVE)
            self._app_indicator.set_menu(self._main_menu)

    def show_main_infobar_message(self,
                                  message: str,
                                  markup: bool = False) -> None:
        if markup:
            self._main_infobar_label.set_markup(message)
        else:
            self._main_infobar_label.set_label(message)
        self._main_infobar.set_revealed(True)

    def toggle_window_visibility(self) -> None:
        if self._window.props.visible:
            self._window.hide()
        else:
            self._window.show()

    def get_power_limit(self) -> Tuple[int, int]:
        return 0, self._power_limit_adjustment.get_value()

    def show_about_dialog(self) -> None:
        self._about_dialog.show()

    def set_statusbar_text(self, text: str) -> None:
        self._statusbar.remove_all(self._context)
        self._statusbar.push(self._context, text)

    def refresh_status(self, status: Optional[Status], gpu_index: int) -> None:
        LOG.debug('view status')
        if status:
            gpu_status = status.gpu_status_list[gpu_index]
            if self._first_refresh:
                self._first_refresh = False
                self._set_entry_text(self._info_name_entry,
                                     gpu_status.info.name)
                self._set_entry_text(self._info_vbios_entry,
                                     gpu_status.info.vbios)
                self._set_entry_text(self._info_driver_entry,
                                     gpu_status.info.driver)
                self._set_entry_text(self._info_cuda_entry, "{}",
                                     gpu_status.info.cuda_cores)
                self._set_entry_text(self._info_uuid_entry,
                                     gpu_status.info.uuid)
                self._set_entry_text(self._info_memory_interface_entry,
                                     "{} bit",
                                     gpu_status.info.memory_interface)
                self._set_entry_text(self._power_min_entry, "{} W",
                                     gpu_status.power.minimum)
                self._set_entry_text(self._power_max_entry, "{} W",
                                     gpu_status.power.maximum)
                self._set_label_markup(self._temp_max_gpu_value,
                                       "<span size=\"large\">{}</span> °C",
                                       gpu_status.temp.maximum)
                self._set_label_markup(self._temp_slowdown_value,
                                       "<span size=\"large\">{}</span> °C",
                                       gpu_status.temp.slowdown)
                self._set_label_markup(self._temp_shutdown_value,
                                       "<span size=\"large\">{}</span> °C",
                                       gpu_status.temp.shutdown)
                self._overclock_frame.set_sensitive(
                    gpu_status.overclock.available)
                self._overclock_warning_label.set_visible(
                    not gpu_status.overclock.available)
                self._fan_profile_frame.set_sensitive(
                    gpu_status.fan.control_allowed)
                self._fan_warning_label.set_visible(
                    not gpu_status.fan.control_allowed)
                self._remove_level_bar_offsets(self._info_gpu_usage_levelbar)
                self._remove_level_bar_offsets(
                    self._info_memory_usage_levelbar)
                self._remove_level_bar_offsets(
                    self._info_encoder_usage_levelbar)
                self._remove_level_bar_offsets(
                    self._info_decoder_usage_levelbar)
                minimum = gpu_status.power.minimum
                maximum = gpu_status.power.maximum
                default = gpu_status.power.default
                if minimum is not None and maximum is not None and default is not None and minimum != maximum:
                    limit = gpu_status.power.limit
                    self._power_limit_adjustment.set_lower(minimum)
                    self._power_limit_adjustment.set_upper(maximum)
                    self._power_limit_adjustment.set_value(limit)
                    self._power_limit_scale.clear_marks()
                    self._power_limit_scale.add_mark(default,
                                                     Gtk.PositionType.BOTTOM,
                                                     f"{default:.0f}")
                    self._power_limit_scale.set_sensitive(True)
                    self._power_limit_apply_button.set_sensitive(True)
                else:
                    self._power_limit_scale.set_sensitive(False)
                    self._power_limit_apply_button.set_sensitive(False)

            self._set_entry_text(self._info_pcie_entry,
                                 "{}x Gen{} @ {}x Gen{}",
                                 gpu_status.info.pcie_max_link,
                                 gpu_status.info.pcie_max_generation,
                                 gpu_status.info.pcie_current_link,
                                 gpu_status.info.pcie_current_generation)
            self._set_entry_text(self._info_memory_entry, "{} MiB / {} MiB",
                                 gpu_status.info.memory_used,
                                 gpu_status.info.memory_total)
            self._set_entry_text(self._info_memory_usage_entry, "{}%",
                                 gpu_status.info.memory_usage)
            self._set_entry_text(self._info_gpu_usage_entry, "{}%",
                                 gpu_status.info.gpu_usage)
            self._set_entry_text(self._info_encoder_usage_entry, "{}%",
                                 gpu_status.info.encoder_usage)
            self._set_entry_text(self._info_decoder_usage_entry, "{}%",
                                 gpu_status.info.decoder_usage)
            self._set_entry_text(self._power_draw_entry, "{:.2f} W",
                                 gpu_status.power.draw)
            self._set_entry_text(self._power_limit_entry, "{:.0f} W",
                                 gpu_status.power.limit)
            self._set_entry_text(self._power_default_entry, "{:.0f} W",
                                 gpu_status.power.default)
            self._set_entry_text(self._power_enforced_entry, "{:.0f} W",
                                 gpu_status.power.enforced)
            self._set_entry_text(self._clocks_graphics_current_entry, "{} MHz",
                                 gpu_status.clocks.graphic_current)
            self._set_entry_text(self._clocks_graphics_max_entry, "{} MHz",
                                 gpu_status.clocks.graphic_max)
            self._set_entry_text(self._clocks_sm_current_entry, "{} MHz",
                                 gpu_status.clocks.sm_current)
            self._set_entry_text(self._clocks_sm_max_entry, "{} MHz",
                                 gpu_status.clocks.sm_max)
            self._set_entry_text(self._clocks_memory_current_entry, "{} MHz",
                                 gpu_status.clocks.memory_current)
            self._set_entry_text(self._clocks_memory_max_entry, "{} MHz",
                                 gpu_status.clocks.memory_max)
            self._set_entry_text(self._clocks_video_current_entry, "{} MHz",
                                 gpu_status.clocks.video_current)
            self._set_entry_text(self._clocks_video_max_entry, "{} MHz",
                                 gpu_status.clocks.video_max)
            self._set_level_bar(self._info_gpu_usage_levelbar,
                                gpu_status.info.gpu_usage)
            self._set_level_bar(self._info_memory_usage_levelbar,
                                gpu_status.info.memory_usage)
            self._set_level_bar(self._info_encoder_usage_levelbar,
                                gpu_status.info.encoder_usage)
            self._set_level_bar(self._info_decoder_usage_levelbar,
                                gpu_status.info.decoder_usage)
            if gpu_status.overclock.available:
                self._set_entry_text(self._overclock_gpu_offset_entry,
                                     "{} MHz", gpu_status.overclock.gpu_offset)
                self._set_entry_text(self._overclock_mem_offset_entry,
                                     "{} MHz",
                                     gpu_status.overclock.memory_offset)
            self._set_label_markup(self._temp_gpu_value,
                                   "<span size=\"xx-large\">{}</span> °C",
                                   gpu_status.temp.gpu)
            for index, value in enumerate(self._fan_duty):
                if gpu_status.fan.fan_list and index < len(
                        gpu_status.fan.fan_list):
                    self._set_label_markup(value,
                                           "<span size=\"large\">{}</span> %",
                                           gpu_status.fan.fan_list[index][0])
                    self._set_label_markup(
                        self._fan_rpm[index],
                        "<span size=\"large\">{}</span> RPM",
                        gpu_status.fan.fan_list[index][1])
                else:
                    value.set_visible(False)
                    self._fan_rpm[index].set_visible(False)

            if self._app_indicator:
                if self._settings_interactor.get_bool(
                        'settings_show_app_indicator'):
                    self._app_indicator.set_status(
                        AppIndicator3.IndicatorStatus.ACTIVE)
                else:
                    self._app_indicator.set_status(
                        AppIndicator3.IndicatorStatus.PASSIVE)
                if self._settings_interactor.get_bool(
                        'settings_app_indicator_show_gpu_temp'
                ) and gpu_status.temp.gpu:
                    self._app_indicator.set_label(f" {gpu_status.temp.gpu}°C",
                                                  " XX°C")
                else:
                    self._app_indicator.set_label("", "")

    @staticmethod
    def _set_entry_text(label: Gtk.Entry, text: Optional[str],
                        *args: Any) -> None:
        if text is not None and None not in args:
            label.set_sensitive(True)
            label.set_text(text.format(*args))
        else:
            label.set_sensitive(False)
            label.set_text('')

    @staticmethod
    def _set_label_markup(label: Gtk.Label, markup: Optional[str],
                          *args: Any) -> None:
        if markup is not None and None not in args:
            label.set_sensitive(True)
            label.set_markup(markup.format(*args))
        else:
            label.set_sensitive(False)
            label.set_markup('')

    @staticmethod
    def _remove_level_bar_offsets(levelbar: Gtk.LevelBar) -> None:
        levelbar.remove_offset_value("low")
        levelbar.remove_offset_value("high")
        levelbar.remove_offset_value("full")
        levelbar.remove_offset_value("alert")

    @staticmethod
    def _set_level_bar(levelbar: Gtk.LevelBar, value: Optional[int]) -> None:
        if value is not None:
            levelbar.set_value(value / 100)
            levelbar.set_sensitive(True)
        else:
            levelbar.set_value(0)
            levelbar.set_sensitive(False)

    def refresh_chart(self,
                      profile: Optional[FanProfile] = None,
                      reset: bool = False) -> None:
        if profile is None and reset is None:
            raise ValueError("Both parameters are note!")

        if reset:
            self._plot_chart({})
        else:
            self._plot_chart(get_fan_profile_data(profile))

    def refresh_fan_profile_combobox(self, data: List[Tuple[int, str]],
                                     active: Optional[int]) -> None:
        self._fan_liststore.clear()
        for item in data:
            self._fan_liststore.append([item[0], item[1]])
        self._fan_combobox.set_model(self._fan_liststore)
        self._fan_combobox.set_sensitive(len(self._fan_liststore) > 1)
        if active is not None:
            self._fan_combobox.set_active(active)
        else:
            self.refresh_chart(reset=True)

    def set_apply_fan_profile_button_enabled(self, enabled: bool) -> None:
        self._fan_apply_button.set_sensitive(enabled)

    def set_edit_fan_profile_button_enabled(self, enabled: bool) -> None:
        self._fan_edit_button.set_sensitive(enabled)

    def set_apply_overclock_profile_button_enabled(self,
                                                   enabled: bool) -> None:
        self._overclock_apply_button.set_sensitive(enabled)

    def set_edit_overclock_profile_button_enabled(self, enabled: bool) -> None:
        self._overclock_edit_button.set_sensitive(enabled)

    def refresh_overclock_profile_combobox(self, data: List[Tuple[int, str]],
                                           active: Optional[int]) -> None:
        self._overclock_liststore.clear()
        for item in data:
            self._overclock_liststore.append([item[0], item[1]])
        self._overclock_combobox.set_model(self._overclock_liststore)
        self._overclock_combobox.set_sensitive(
            len(self._overclock_liststore) > 1)
        if active is not None:
            self._overclock_combobox.set_active(active)

    # pylint: disable=attribute-defined-outside-init
    def _init_plot_charts(self,
                          fan_scrolled_window: Gtk.ScrolledWindow) -> None:
        self._fan_figure = Figure(figsize=(8, 6),
                                  dpi=72,
                                  facecolor='#00000000')
        self._fan_canvas = FigureCanvas(self._fan_figure)  # a Gtk.DrawingArea+
        self._fan_axis = self._fan_figure.add_subplot(111)
        self._fan_line, = init_plot_chart(fan_scrolled_window,
                                          self._fan_figure, self._fan_canvas,
                                          self._fan_axis)

    def _plot_chart(self, data: Dict[int, int]) -> None:
        sorted_data = OrderedDict(sorted(data.items()))
        temperature = list(sorted_data.keys())
        duty = list(sorted_data.values())
        self._fan_line.set_xdata(temperature)
        self._fan_line.set_ydata(duty)
        self._fan_canvas.draw()
        self._fan_canvas.flush_events()
示例#27
0
class Main:
    going = False
    iterc = 5
    bars = None

    def __init__(self):
        self.win = Gtk.Window()
        self.win.connect("delete-event", Gtk.main_quit)
        self.win.set_default_size(720, 480)
        self.fig = Figure(figsize=(10, 10), dpi=100)
        self.ax = self.fig.add_subplot()
        self.canvas = FigureCanvas(self.fig)
        sw = Gtk.ScrolledWindow()
        sw.set_border_width(10)
        sw.add(self.canvas)
        upperside = Gtk.ButtonBox(orientation=Gtk.Orientation.VERTICAL)
        self.fill_btnbox(upperside, TIMINGS)
        lowerside = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.spin = Gtk.SpinButton()
        self.spin.set_range(1,
                            2**16)  #TODO: find out how to remove upper bound
        self.spin.set_increments(1, 10)
        self.spin.set_value(self.iterc)
        self.spin.connect("value-changed", self._on_spin)
        lowerside.pack_end(self.spin, False, True, 0)
        lowerside.pack_end(Gtk.Label.new("↓Iterations↓"), False, True, 0)
        self.progr2 = Gtk.ProgressBar()
        lowerside.pack_end(self.progr2, False, True, 2)
        self.progr1 = Gtk.ProgressBar()
        lowerside.pack_end(self.progr1, False, True, 2)
        sidebar = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        sidebar.pack_start(upperside, False, True, 10)
        sidebar.pack_start(lowerside, True, True, 2)
        self.box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
        self.box.pack_start(sidebar, False, True, 2)
        self.box.pack_start(sw, True, True, 0)
        self.win.add(self.box)
        self.win.show_all()
        self.progr1.set_opacity(0)
        self.progr2.set_opacity(0)

    def measure(self,
                todos: Iterable[Timing]) -> Tuple[List[str], List[float]]:
        self.set_progress(0)
        names = []
        vals = []
        todolen = len(todos)
        for i, todo in enumerate(reversed(todos)):
            self.set_progress(i / todolen)
            t = Timer(*todo)
            t.evaluate()
            names.append(t.name)
            vals.append(t.value)
        self.set_progress(1.0)
        return names, vals

    def fill_btnbox(self, btnbox: Gtk.ButtonBox, timings: Dict[str, Timing]):
        for name in timings.keys():
            btn = Gtk.Button(label=name)
            btn.connect("button-press-event", self._on_start)
            btnbox.pack_start(btn, False, True, 0)

    def set_progress(self, fraction: float, upper: bool = False):
        if upper:
            progr = self.progr1
        else:
            progr = self.progr2
        progr.set_fraction(fraction)
        if not upper:
            while Gtk.events_pending():
                Gtk.main_iteration_do(False)

    def set_bars(self, cache: Dict[str, List[float]]):
        names = tuple(cache.keys())
        means = []
        errs = ([], [])
        for samples in cache.values():
            m = mean(samples)
            errs[0].append(m - min(samples))
            errs[1].append(max(samples) - m)
            means.append(m)
        if self.bars:
            self.ax.clear()
        self.ax.xaxis.set_major_formatter(MPLFormatter("%0.2fµs"))
        self.bars = self.ax.barh(names,
                                 means,
                                 xerr=errs,
                                 capsize=80 / len(cache))
        self.fig.tight_layout()
        self.canvas.draw()

    def _on_start(self, widget: Gtk.Button, event: Gdk.EventButton) -> bool:
        if self.going:
            return True
        self.going = True
        self.spin.set_range(self.iterc, self.iterc)
        self.progr1.set_opacity(1)
        self.progr2.set_opacity(1)
        self.set_progress(0, True)
        self.set_progress(0, False)
        timings = TIMINGS[widget.get_label()]
        cache = {timing[0]: [] for timing in timings}
        iterc = self.iterc
        for i in range(1, iterc + 1):
            for name, val in zip(*self.measure(timings)):
                cache[name].append(val)
            self.set_bars(cache)
            self.set_progress(i / iterc, True)
        self.progr1.set_opacity(0)
        self.progr2.set_opacity(0)
        self.going = False
        self.spin.set_range(1, 2**16)
        return True

    def _on_spin(self, widget: Gtk.SpinButton) -> bool:
        self.iterc = int(widget.get_value())
        return True
示例#28
0
class DropFitView(View['DropFitPresenter', Gtk.Widget]):
    def _do_init(self) -> Gtk.Widget:
        from matplotlib.backends.backend_gtk3agg import FigureCanvasGTK3Agg as FigureCanvas
        from matplotlib.figure import Figure
        from matplotlib.image import AxesImage

        self._widget = Gtk.Grid()

        figure = Figure(tight_layout=True)

        self._figure_canvas = FigureCanvas(figure)
        self._figure_canvas.props.hexpand = True
        self._figure_canvas.props.vexpand = True
        self._figure_canvas.show()
        self._widget.add(self._figure_canvas)

        # Axes
        self._axes = figure.add_subplot(1, 1, 1)
        self._axes.set_aspect('equal', 'box')
        self._axes.xaxis.tick_top()
        for item in (*self._axes.get_xticklabels(),
                     *self._axes.get_yticklabels()):
            item.set_fontsize(8)

        self._axes_bg_image = AxesImage(ax=self._axes)

        # Placeholder transparent 1x1 image (rgba format)
        self._axes_bg_image.set_data(np.zeros((1, 1, 4)))
        self._axes.add_image(self._axes_bg_image)

        self._profile_extract_line = self._axes.plot([],
                                                     linestyle='-',
                                                     color='#0080ff',
                                                     linewidth=1.5)[0]
        self._profile_fit_line = self._axes.plot([],
                                                 linestyle='-',
                                                 color='#ff0080',
                                                 linewidth=1)[0]

        self.presenter.view_ready()

        return self._widget

    def set_drop_image(self, image: Optional[np.ndarray]) -> None:
        if image is None:
            self._axes.set_axis_off()
            self._axes_bg_image.set_data(np.zeros((1, 1, 4)))
            self._figure_canvas.draw()
            return

        self._axes.set_axis_on()

        # Use a scaled down image so it draws faster.
        thumb_size = (min(400, image.shape[1]), min(400, image.shape[0]))
        image_thumb = cv2.resize(image, dsize=thumb_size)
        self._axes_bg_image.set_data(image_thumb)

        self._axes_bg_image.set_extent((0, image.shape[1], image.shape[0], 0))
        self._figure_canvas.draw()

    def set_drop_profile_extract(self, profile: Optional[np.ndarray]) -> None:
        if profile is None:
            self._profile_fit_line.set_visible(False)
            self._figure_canvas.draw()
            return

        self._profile_fit_line.set_data(profile.T)
        self._profile_fit_line.set_visible(True)
        self._figure_canvas.draw()

    def set_drop_profile_fit(self, profile: Optional[np.ndarray]) -> None:
        if profile is None:
            self._profile_extract_line.set_visible(False)
            self._figure_canvas.draw()
            return

        self._profile_extract_line.set_data(profile.T)
        self._profile_extract_line.set_visible(True)
        self._figure_canvas.draw()

    def _do_destroy(self) -> None:
        self._widget.destroy()
示例#29
0
class PlotWindow(Gtk.Window):
    def __init__(self):
        super(PlotWindow, self).__init__()
        self.connect('destroy', Gtk.main_quit)

        self.box = Gtk.Box(spacing=6, orientation=Gtk.Orientation(1))
        self.add(self.box)

        self.switch = Gtk.Switch()
        self.switch.connect("notify::active", self.on_switch_toggled)
        self.switch.set_active(False)
        self.box.pack_start(self.switch, True, True, 0)

        self.progress = Gtk.ProgressBar(show_text=True)
        self.box.pack_start(self.progress, True, True, 0)

        # global line, ax, canvas
        self.fig = Figure()
        self.ax = self.fig.add_subplot(111)
        self.ax.set_xlim(0, 30)
        self.ax.set_ylim([0, 255])
        self.ax.set_autoscale_on(False)
        self.data = []
        self.l_data, = self.ax.plot([], self.data, label='MagY')
        self.ax.legend()
        self.canvas = FigureCanvas(self.fig)
        self.canvas.set_size_request(800, 600)
        self.canvas.show()
        self.box.pack_start(self.canvas, True, True, 0)
        # self.line, = self.ax.plot([1, 2, 3], [1, 2, 10])

        port = '/dev/ttyACM0'
        baud = 9600
        self.arduino = ArdTest(self, port, baud)
        # arduino.open_conn()

    def on_switch_toggled(self, switch, gparam):
        if switch.get_active():
            state = "on"
            self.arduino.open_conn()
        else:
            state = "off"
            self.arduino.close()
        print("Switch was turned", state)

    def update_progress(self, ok, bad):
        self.progress.pulse()
        self.progress.set_text(str(ok) + ' OK, ' + str(bad) + ' BAD')
        return False

    def update_plot(self, result):
        # print(threading.current_thread().getName())
        # self.line.set_ydata([1, result, 10])
        # self.ax.draw_artist(self.line)
        # self.canvas.draw()
        self.data.append(result)
        # print(self.data)
        self.l_data.set_data(range(len(self.data)), self.data)
        # print(self.l_data)
        try:
            self.canvas.draw()
        except Exception as e:
            print(e)
        return False
示例#30
0
文件: plotgui.py 项目: metocean/pysmc
class SMCPlotGui:
    """ PYGtk GUI class wrapper for displaying SMC gridded data """

    def __init__(self, filename=None):
        # initialise some variables:
        self.ncfn = filename
        self.pc = None
        self.cfacs = None
        self.proj = None
        self.src_proj = None

        self.lon1=None
        self.lon2=None
        self.lat1=None
        self.lat2=None

        ###############
        ## GTK setup ##
        ###############

        # create new window
        self.win = Gtk.Window(Gtk.WindowType.TOPLEVEL)

        ######################
        # setup window
        ######################
        self.win.set_border_width(10)
        self.win.set_default_size(1200, 500)
        self.win.set_title('SMC Gridded Data Plotter')

        ######################
        # add the GTK canvas:
        ######################
        self.fig = plt.Figure(figsize=(4,3), dpi=100)
        self.canvas = FigureCanvas(self.fig)

        ################
        # Add menu bar #
        ################
        menu_bar = Gtk.MenuBar()
        file_menu = Gtk.Menu()
        open_item = Gtk.MenuItem("Open")
        exit_item = Gtk.MenuItem("Exit")
        file_menu.append(open_item)
        file_menu.append(exit_item)

        open_item.connect("activate", self.load_event)

        root_menu = Gtk.MenuItem("File")
        root_menu.set_submenu(file_menu);
        menu_bar.append(root_menu)


        ###########
        # Controls
        ##########

        # buttons:
        btnPlot = Gtk.Button('Update Plot')
        btnPrev = Gtk.Button('Prev Time')
        btnNext = Gtk.Button('Next Time')

        # Field combo box:
        store = Gtk.ListStore(str,str)
        self.cbox_field = Gtk.ComboBox.new_with_model_and_entry(store)
        cell = Gtk.CellRendererText()
        self.cbox_field.pack_start(cell, True)
        self.cbox_field.add_attribute(cell, 'text', 1)
        self.cbox_field.set_entry_text_column(1)
        store.append(['hs','sig wave heihgt'])


        # Times combo box:
        store = Gtk.ListStore(int,str)
        self.cbox_times = Gtk.ComboBox.new_with_model_and_entry(store)
        cell = Gtk.CellRendererText()
        self.cbox_times.pack_start(cell, True)
        self.cbox_times.add_attribute(cell, 'text', 1)
        self.cbox_times.set_entry_text_column(1)
        #for i in range(1,61):
        #    store.append([i-1, 'T+%03d' % i])

        # Domain combo box:
        store = Gtk.ListStore(str,float,float,float,float)
        self.cbox_domains = Gtk.ComboBox.new_with_model_and_entry(store)
        cell = Gtk.CellRendererText()
        self.cbox_domains.pack_start(cell, True)
        self.cbox_domains.add_attribute(cell, 'text', 0)
        store.append(['Full Domain (could be slow)', -999.9, -999.9, -999.9, -999.9])
        store.append(['UK', 35.0, 70.0, -15.0, 10.0])
        store.append(['South West UK', 49.4, 51.5, -6.7, -1.6])
        store.append(['Mediterranean', 29.5, 46.5, -6.0, 36.5])
        store.append(['North Atlantic', 20.0, 70.0, -90, 30])
        store.append(['West Pacific', -70.0, 70.0, 120, 200])
        store.append(['East Pacific', -70.0, 70.0, -160, -68])
        store.append(['Arabian Gulf', 23.0, 30.5, 47.5, 59.5])
        store.append(['Caspian Sea', 36.0, 47.5, 46.0, 55.5])
        store.append(['Black Sea', 40.5, 47.1, 27.0, 42.0])
        store.append(['Caribbean', 10.0, 27.5, -86.5, -58.5])
        store.append(['South China Sea', -9.5, 24.0, 98.0, 128.0])
        store.append(['Australasia', -48, 0.0, 105.0, 179.0])
        store.append(['New Zealand', -50, -30, 160.0, 182.0])
        self.cbox_domains.set_entry_text_column(0)
        self.cbox_domains.set_active(1)


        # Projections:
        store = Gtk.ListStore(object, str)
        self.cbox_proj = Gtk.ComboBox.new_with_model_and_entry(store)
        cell = Gtk.CellRendererText()
        self.cbox_proj.pack_start(cell, True)
        self.cbox_proj.add_attribute(cell, 'text', 1)
        self.cbox_proj.set_entry_text_column(1)
        store.append([ccrs.PlateCarree(), 'Plate Carree'])
        store.append([ccrs.RotatedPole(pole_latitude=37.5, pole_longitude=177.5),'Euro Rotated Pole'])
        store.append([ccrs.Robinson(), 'Robinson'])
        store.append([ccrs.Mercator(), 'Mercator'])
        store.append([ccrs.Geostationary(), 'Geostationary'])
        store.append([ccrs.PlateCarree(central_longitude=180), 'Plate Carree (central_longitude=180)'])

        self.cbox_proj.set_active(0)

        # coastlines:
        store = Gtk.ListStore(object, str)
        self.cbox_coast = Gtk.ComboBox.new_with_model_and_entry(store)
        cell = Gtk.CellRendererText()
        self.cbox_coast.pack_start(cell, True)
        self.cbox_coast.add_attribute(cell, 'text', 1)
        self.cbox_coast.set_entry_text_column(1)
        store.append([None, 'None'])
        store.append(['10m', 'High res (10m)'])
        store.append(['50m', 'Medium res (50m)'])
        store.append(['110m', 'Low res (110m)'])

        self.cbox_coast.set_active(3)
        self.coast = '110m'

        # lat/lon ranges:
        self.inLat1 = Gtk.Entry();
        self.inLat2 = Gtk.Entry();
        self.inLon1 = Gtk.Entry();
        self.inLon2 = Gtk.Entry();
        self.domain_changed_event(self.cbox_domains) # update with default domain

        # Cell size selection
        cellsbox = Gtk.HBox(homogeneous=False, spacing=5)
        self.chkf1 = Gtk.CheckButton("1")
        self.chkf2 = Gtk.CheckButton("2")
        self.chkf3 = Gtk.CheckButton("3")
        self.chkf4 = Gtk.CheckButton("4")
        cellsbox.pack_end(self.chkf4, True, True, 0)
        cellsbox.pack_end(self.chkf3, True, True, 0)
        cellsbox.pack_end(self.chkf2, True, True, 0)
        cellsbox.pack_end(self.chkf1, True, True, 0)

        # Colour range box:
        crangebox = Gtk.HBox(homogeneous=False, spacing=5)
        self.cmin = Gtk.Entry()
        self.cmax = Gtk.Entry()
        self.cauto = Gtk.CheckButton('Auto')
        crangebox.pack_start(self.cmin, True, True, 0)
        crangebox.pack_start(self.cmax, True, True, 0)
        crangebox.pack_start(self.cauto, True, True, 0)
        self.cauto.set_active(True)
        self.cmin.set_sensitive(False)
        self.cmax.set_sensitive(False)

        self.cauto.connect('toggled', self.cauto_changed_event)


        ## controls layout
        grid = Gtk.Table(rows=8, columns=3)
        grid.attach(Gtk.Label(label='Field'),     0, 1, 0, 1, yoptions=Gtk.AttachOptions.SHRINK)
        grid.attach(Gtk.Label(label='Time'),      0, 1, 1, 2, yoptions=Gtk.AttachOptions.SHRINK)
        grid.attach(Gtk.Label(label='Projection'),0, 1, 2, 3, yoptions=Gtk.AttachOptions.SHRINK)
        grid.attach(Gtk.Label(label='Coastline'), 0, 1, 3, 4, yoptions=Gtk.AttachOptions.SHRINK)
        grid.attach(Gtk.Label(label='Domain '),   0, 1, 4, 5, yoptions=Gtk.AttachOptions.SHRINK)
        grid.attach(Gtk.Label(label='Lat Range'), 0, 1, 5, 6, yoptions=Gtk.AttachOptions.SHRINK)
        grid.attach(Gtk.Label(label='Lon Range'), 0, 1, 6, 7, yoptions=Gtk.AttachOptions.SHRINK)
        grid.attach(Gtk.Label(label='Cell Factor'),     0, 1, 7, 8, yoptions=Gtk.AttachOptions.SHRINK)
        grid.attach(Gtk.Label(label='Colour range'),0, 1, 8, 9, yoptions=Gtk.AttachOptions.SHRINK)

        grid.attach(self.cbox_field,        1, 3, 0, 1, yoptions=Gtk.AttachOptions.SHRINK)
        grid.attach(self.cbox_times,        1, 3, 1, 2 ,yoptions=Gtk.AttachOptions.SHRINK)
        grid.attach(self.cbox_proj,         1, 3, 2, 3 ,yoptions=Gtk.AttachOptions.SHRINK)
        grid.attach(self.cbox_coast,        1, 3, 3, 4 ,yoptions=Gtk.AttachOptions.SHRINK)
        grid.attach(self.cbox_domains,      1, 3, 4, 5 ,yoptions=Gtk.AttachOptions.SHRINK)
        grid.attach(self.inLat1,            1, 2, 5, 6, yoptions=Gtk.AttachOptions.SHRINK)
        grid.attach(self.inLat2,            2, 3, 5, 6, yoptions=Gtk.AttachOptions.SHRINK)
        grid.attach(self.inLon1,            1, 2, 6, 7, yoptions=Gtk.AttachOptions.SHRINK)
        grid.attach(self.inLon2,            2, 3, 6, 7, yoptions=Gtk.AttachOptions.SHRINK)
        grid.attach(cellsbox,               1, 3, 7, 8, yoptions=Gtk.AttachOptions.SHRINK)
        grid.attach(crangebox,              1, 3, 8, 9, yoptions=Gtk.AttachOptions.SHRINK)


        #grid.attach(btnPlot,                0, 1, 8, 9, yoptions=Gtk.AttachOptions.SHRINK, xoptions=Gtk.AttachOptions.SHRINK)
        # Hbox for plot buttons
        btn_hbox = Gtk.HBox(homogeneous=False, spacing=5)
        btn_hbox.pack_start(btnPrev, True, False, 0)
        btn_hbox.pack_start(btnPlot, True, False, 0)
        btn_hbox.pack_start(btnNext, True, False, 0)


        ## File details text view
        txt = Gtk.TextBuffer()
        txt.set_text('Please load a file')
        self.tv_file_details = Gtk.TextView.new_with_buffer(txt)

        vbox = Gtk.VBox(spacing=5)
        vbox.pack_start(grid, False, True, 0)
        vbox.pack_start(btn_hbox, False, True, 0)
        vbox.pack_end(self.tv_file_details, True, True, 0)

        # plot controls
        from matplotlib.backends.backend_gtk3 import NavigationToolbar2GTK3 as NavigationToolbar
        toolbar = NavigationToolbar(self.canvas, self.win)
        #vbox.pack_end(toolbar, False, False)

        # Top level layout box:
        topbox = Gtk.VBox()
        topbox.pack_start(menu_bar, False, True, 0)

        box = Gtk.HBox(homogeneous=False, spacing=5)
        topbox.pack_end(box, True, True, 0)

        # canvas/toolbar layout
        plotbox = Gtk.VBox(homogeneous=False, spacing=0)
        plotbox.pack_start(self.canvas, True, True, 0)
        plotbox.pack_end(toolbar, False, False, 0)

        box.pack_start(plotbox, True, True, 0)
        box.pack_end(vbox, False, False, 0)
        self.win.add(topbox)


        ###################
        # connect signals:
        ###################
        # destroy/delete:
        self.win.connect("delete_event", self.delete_event)
        self.win.connect("destroy", self.destroy)

        btnPlot.connect("clicked", self.plot_event)
        btnNext.connect("clicked", self.next_time_event)
        btnPrev.connect("clicked", self.prev_time_event)

        self.cbox_domains.connect('changed', self.domain_changed_event)

        # show window
        self.win.show_all()

        #### Load file, if passed in:
        if self.ncfn is not None:
            self.loadfile(self.ncfn)

    def get_cbox_selection(self, combobox, col=0):
        model = combobox.get_model()
        active = combobox.get_active()
        if active < 0:
            return None
        return model[active][col]

    def delete_event(self, widget, event, data=None):
        # returning false after a delete event destroys the widget,
        # returning true means you don't want to destroy the widget.
        return False


    def cauto_changed_event(self, widget, data=None):
        # update the lat/lon boxes:
        active = widget.get_active()
        self.cmin.set_sensitive(not active)
        self.cmax.set_sensitive(not active)

    def domain_changed_event(self, widget, data=None):
        # update the lat/lon boxes:
        model = widget.get_model()
        active = widget.get_active()
        if active < 0:
            return


        for i,o in enumerate([self.inLat1, self.inLat2,
                              self.inLon1, self.inLon2]):
            val = model[active][i+1]
            if val < -900.0:
                val = ''
            else:
                val = str(val)

            o.set_text(val)

    def destroy(self, widget, data=None):
        Gtk.main_quit()

    def load_event(self, widget, data=None):
        # pop up a file selectro dialog and load the file
        if self.selectfile():
            self.loadfile(self.ncfn)

    def selectfile(self):
        dlg = Gtk.FileChooserDialog(title='Select a SMC netCDF file',
                action=Gtk.FileChooserAction.OPEN,
                buttons=(Gtk.STOCK_CANCEL,Gtk.ResponseType.CANCEL,Gtk.STOCK_OPEN,Gtk.ResponseType.OK))
        dlg.set_default_response(Gtk.ResponseType.OK)

        ret = dlg.run()
        if ret == Gtk.ResponseType.OK:
            self.ncfn = dlg.get_filename()

        dlg.destroy()

        return (ret == Gtk.ResponseType.OK)

    def loadfile(self, fn):
        self.d = nc.Dataset(fn, mode='r')

        if self.d.dimensions.has_key('seapoint'):
            seapoint_dim = 'seapoint'
        else:
            seapoint_dim = 'seapoints'

        # populate text bxo with file details
        txt = self.tv_file_details.get_buffer()
        txt.set_text('File details:\n'  +
            '\tNo. sea points: %d\n' % len(self.d.dimensions[seapoint_dim]) +
            '\tNo. times: %d\n' % len(self.d.dimensions['time']))


        # update the fields combobox
        store = self.cbox_field.get_model()
        store.clear()
        store.append(['grid', 'Grid mesh only'])
        for varname,var in self.d.variables.items():
            if var.ndim == 2 and hasattr(var,'long_name'):
                store.append([varname, var.long_name])
            if var.ndim == 3 and hasattr(var,'long_name'):
                store.append(["ens_"+varname, var.long_name + " (ens)"])

        self.cbox_field.set_active(0)


        # find location of uwnd or vwnd and insert a wspd option (this will calculate
        # a wind speed field from uwnd and vwnd):
        i=store.get_iter_first()
        while i is not None:
            varname = store.get_value(i,0)
            if varname in ['uwnd','vwnd']:
                # insert new field here:
                store.insert_before(i, ['wspd_derived', 'wind speed (derived)'])
                break
            i = store.iter_next(i)

        # update times text box:
        store = self.cbox_times.get_model()
        store.clear()
        t = self.d.variables['time']
        t = nc.num2date(t[:], t.units)
        for itime, fctime in enumerate(t):
            store.append([itime, "%s (T+%03d)" % (fctime.strftime("%d/%m/%Y %H:%M"), itime+1)])
        self.cbox_times.set_active(0)

        # get model extents:
        try:
            self.minlat = float(self.d.southernmost_latitude)
            self.maxlat = float(self.d.northernmost_latitude)
            self.minlon = float(self.d.westernmost_longitude)
            self.maxlon = float(self.d.easternmost_longitude)
        except:
            self.minlat = -90
            self.maxlat = 90
            self.minlon = 0
            self.maxlon = 360



        return

    def plot_event(self, widget, data=None):
        self.plotfield()

    def next_time_event(self, widget, data=None):
        # move to next timestep and replot
        itime = self.get_cbox_selection(self.cbox_times)
        if itime is None:
            return

        itime = itime + 1
        ntimes = len(self.cbox_times.get_model())

        if itime >= ntimes:
            itime = 0

        self.cbox_times.set_active(itime);
        self.plot_event(None)

    def prev_time_event(self, widget, data=None):
        # move to next timestep and replot
        itime = self.get_cbox_selection(self.cbox_times)
        if itime is None:
            return

        itime = itime - 1
        ntimes = len(self.cbox_times.get_model())

        if itime < 0:
            itime = ntimes - 1

        self.cbox_times.set_active(itime);
        self.plot_event(None)


    def getfloat(self, string):
        try:
            return float(string)
        except ValueError:
            return None

    def plotfield(self):

        # get reference to details text view and clear it
        txt = self.tv_file_details.get_buffer()
        start_iter = txt.get_start_iter()
        end_iter = txt.get_end_iter()
        txt.delete(start_iter, end_iter)
        end_iter = txt.get_end_iter()


        # get required field, time, etc:
        var = self.get_cbox_selection(self.cbox_field)
        if var.startswith('ens_'):
            var = var[4:]
            ens = True
        else:
            ens = False

        itime = self.get_cbox_selection(self.cbox_times)


        # get lat/lon ranges
        lat1 = self.getfloat(self.inLat1.get_text())
        lat2 = self.getfloat(self.inLat2.get_text())
        lon1 = self.getfloat(self.inLon1.get_text())
        lon2 = self.getfloat(self.inLon2.get_text())

        # get celfacs:
        cfacs=[]
        if self.chkf1.get_active():
            cfacs.append(1)
        if self.chkf2.get_active():
            cfacs.append(2)
        if self.chkf3.get_active():
            cfacs.append(4)
        if self.chkf4.get_active():
            cfacs.append(8)

        if len(cfacs) == 0:
            cfacs = None

        if cfacs != self.cfacs:
            self.pc = None
            self.cfacs = cfacs


        if(lat1 != self.lat1 or lat2 != self.lat2 or
                lon1 != self.lon1 or lon2 != self.lon2 ):

            self.pc = None
            self.lat1 = lat1
            self.lat2 = lat2
            self.lon1 = lon1
            self.lon2 = lon2

        proj = self.get_cbox_selection(self.cbox_proj)
        if self.proj != proj:
            self.proj = proj
            self.pc = None
            self.fig.clf()
            self.ax = self.fig.add_subplot(111, projection=self.proj)
            sm = plt.cm.ScalarMappable(norm=plt.Normalize())
            sm._A=[]
            self.cbar = plt.colorbar(sm, ax=self.ax, orientation='horizontal', fraction=0.05, shrink=0.8, pad=0.04)

        coast = self.get_cbox_selection(self.cbox_coast)
        if self.coast != coast:
            newcoast = True
            self.coast = coast
        else:
            newcoast = False

        ax = self.ax

        # determin extents:
        if isinstance(proj, ccrs.Geostationary) or (
                lon1 is None and lon2 is None and lat1 is None and lat2 is None):
            ax.set_global()
            global_extent = True
        else:
            if lon1 is None:
                lon1 = self.minlon
            if lon2 is None:
                lon2 = self.maxlon
            if lat1 is None:
                lat1 = self.minlat
            if lat2 is None:
                lat2 = self.maxlat
            global_extent = False


        ## check source projection of requested variable:
        chkvar = var
        if var == 'wspd_derived': chkvar = 'uwnd'
        if var == 'grid': chkvar = 'hs'
        if hasattr(self.d.variables[chkvar], "grid_mapping"):
            # get rotated pole projection:
            mapname = self.d.variables[chkvar].grid_mapping
            gmap = self.d.variables[mapname]
            plat = gmap.grid_north_pole_latitude
            plon = gmap.grid_north_pole_longitude
            src_proj = ccrs.RotatedPole(pole_latitude=plat, pole_longitude=plon)
        else:
            src_proj = None

        if self.src_proj != src_proj:
            # source projection changed need to update patches:
            self.pc = None
            self.src_proj = src_proj


        # If patch collection not yet calculated, then build it now and add it to
        # the axis along with the coastlines:
        if self.pc is None:
            txt.insert(end_iter, "Domain has changed - recalculating patches...")
            while Gtk.events_pending(): Gtk.main_iteration_do(True)

            self.pc = smc.generate_patch_collection(self.d,
                    lon1=self.lon1, lon2=self.lon2,
                    lat1=self.lat1, lat2=self.lat2,
                    target_crs=self.proj, cfacs=cfacs,
                    source_crs=self.src_proj)

            end_iter = txt.get_end_iter()
            txt.insert(end_iter, "Done\n")
            while Gtk.events_pending(): Gtk.main_iteration_do(True)

            end_iter = txt.get_end_iter()
            txt.insert(end_iter, "Adding patches to axes\n");
            print("Adding patches to axes\n")
            while Gtk.events_pending(): Gtk.main_iteration_do(True)

            ax.cla()
            self.cm = ax.add_collection(self.pc.pcol)

            if not global_extent:
                ax.set_extent((lon1, lon2, lat1, lat2), crs=ccrs.PlateCarree())

            if self.coast is not None:
                end_iter = txt.get_end_iter()
                txt.insert(end_iter, "Adding coastline\n");
                while Gtk.events_pending(): Gtk.main_iteration_do(True)
                ax.coastlines(resolution=self.coast)

        elif newcoast:
            # coastline changed; clear axis and redraw:
            ax.cla()

            end_iter = txt.get_end_iter()
            txt.insert(end_iter, "Adding patches to axes\n");
            while Gtk.events_pending(): Gtk.main_iteration_do(True)
            self.cm = ax.add_collection(self.pc.pcol)

            if not global_extent:
                ax.set_extent((lon1, lon2, lat1, lat2), crs=ccrs.PlateCarree())

            if self.coast is not None:
                end_iter = txt.get_end_iter()
                txt.insert(end_iter, "Adding coastline\n");
                while Gtk.events_pending(): Gtk.main_iteration_do(True)
                ax.coastlines(resolution=self.coast)


        # update the patch face colours with the new data:
        end_iter = txt.get_end_iter()
        txt.insert(end_iter, "Updating patches...\n");
        while Gtk.events_pending(): Gtk.main_iteration_do(True)

        if var == 'grid':
            # special case - just plot grid mesh:
            self.pc.pcol.set_facecolor('#EAEAEA')
            self.pc.pcol.set_edgecolor('#5E5E5E')
            self.pc.pcol.set_linewidth(0.5)
            cmin = 0
            cmax = 1
        else:
            # load field and set face colours
            if var == 'wspd_derived':
                end_iter = txt.get_end_iter()
                txt.insert(end_iter, "Deriving wind speed from uwnd and vwnd fields\n")
                fld = self.d.variables['uwnd']
                fld2 = self.d.variables['vwnd']
                dat = np.sqrt(
                        np.power(fld[itime,:][self.pc.mask], 2) +
                        np.power(fld2[itime,:][self.pc.mask], 2) )
            else:
                fld = self.d.variables[var]
                if ens:
                    dat = fld[0,itime,:][self.pc.mask]  # just get member 0
                else:
                    dat = fld[itime,:][self.pc.mask]

            if self.cauto.get_active():
                cmin = dat.min()
                cmax = dat.max()
                self.cmin.set_text("%.2f" % cmin)
                self.cmax.set_text("%.2f" % cmax)
            else:
                cmin = self.getfloat(self.cmin.get_text())
                cmax = self.getfloat(self.cmax.get_text())

            clrs = smc.generate_color_array(dat, cmin=cmin, cmax=cmax)
            self.pc.pcol.set_facecolor(clrs)
            self.pc.pcol.set_edgecolor(clrs)
            self.pc.pcol.set_linewidth(0.5)


        # update colorbar mappable with new range:
        self.cbar.mappable.set_clim(cmin, cmax)

        ## update title
        fldname = self.get_cbox_selection(self.cbox_field, 1)
        time = self.get_cbox_selection(self.cbox_times, 1)
        ax.set_title("%s @ %s" % (fldname, time), fontsize=12)

        # update canvas
        self.canvas.draw()
        end_iter = txt.get_end_iter()
        txt.insert(end_iter, "Done.\n");
        while Gtk.events_pending(): Gtk.main_iteration_do(True)

    def main(self):
        Gtk.main()
示例#31
0
class GUI:
    def __init__(self):
        self.last_dir = os.getcwd()
        self.b = Gtk.Builder()
        gui_xml_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'test_blob_detector_gui.xml')
        self.b.add_from_file(gui_xml_path)
        self.window = self.b.get_object("window")
        self.window.set_title('BlobDetector')

        self.f = matplotlib.figure.Figure()
        self.ax = self.f.add_subplot(111)
        self.f.subplots_adjust(left=0.01, right=0.99, bottom=0.01, top=0.99, hspace=0, wspace=0)

        self.canvas = FigureCanvas(self.f)
        self.b.get_object("alignment_img").add(self.canvas)

        grid = self.b.get_object("grid_params")

        j = 0
        self.detector_params_toggle_buttons = {}
        self.detector_params_entries = {}
        for p in detector_params_desc:
            if isinstance(p, dict):
                button = Gtk.CheckButton(label=p['name'])
                grid.attach(button, 0, j, 1, 1)
                self.detector_params_toggle_buttons[p['name']]= button
                j+=1
                for sp in p['params']:
                    label = Gtk.Label(label='{}'.format(sp))
                    label.set_justify(Gtk.Justification.LEFT)
                    grid.attach(label, 0, j, 1, 1)
                    if 0:
                        adj = Gtk.Adjustment(0, 0, 100, 5, 10, 0)
                        scale = Gtk.Scale(orientation=Gtk.Orientation.HORIZONTAL, adjustment=adj)
                        grid.attach(scale, 1, j, 2, 1)
                    else:
                        entry = Gtk.Entry()
                        grid.attach(entry, 1, j, 2, 1)
                        self.detector_params_entries[sp] = entry
                    #print sp
                    j+=1
            else:
                label = Gtk.Label(label=f'{p}')  
                label.set_justify(Gtk.Justification.LEFT)
                grid.attach(label, 0, j, 1, 1)
                entry = Gtk.Entry()
                grid.attach(entry, 1, j, 2, 1)
                self.detector_params_entries[p] = entry
                j+=1

        scale = self.b.get_object("scale_gamma")
        adj_args = {'value':1, 'lower':0.1, 'upper':2., 'step_increment':0.05, 'page_increment':0.1, 'page_size':0}
        adj = Gtk.Adjustment(**adj_args)
        scale.set_adjustment(adj)

        self.image_display_mode = 'Original'
                
        self.window.show_all()

    def display_image(self, model):
        label = self.b.get_object("label_image")
        label.set_text(model.image_path)
        
        img = model.get_image(self.image_display_mode)
        if len(img.shape) == 2:
            img2 = cv2.cvtColor(img, cv2.COLOR_GRAY2RGB)
        else:
            img2 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        self.ax.imshow(img2)
        self.canvas.draw()

    def display_params(self ,params):
        for p in smocap.Detector.param_names:
            a = getattr(params, p)
            if isinstance(a, bool):
                self.detector_params_toggle_buttons[p].set_active(a)
            else:
                self.detector_params_entries[p].set_text(str(a))
                
    def display_detector_res(self, keypoints):
        textview = self.b.get_object("textview1")
        textbuffer = textview.get_buffer()
        txt = "{} keypoints\n\n".format(len(keypoints))
        for kp in keypoints:
            txt += '\tpos: {:.2f} {:.2f}\n'.format(*kp.pt)
            txt += '\tsize: {:.2f}\n'.format(kp.size)
            #txt += '\tangle: {}\n'.format(kp.angle)
            #txt += '\tresp: {}\n'.format(kp.response)
            #txt += '\toctave: {}\n'.format(kp.octave)
            txt += '\n'
        textbuffer.set_text(txt)
            
    def request_path(self, action):
        dialog = Gtk.FileChooserDialog("Please choose a file", self.window, action,
                                       (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                                        Gtk.STOCK_OPEN, Gtk.ResponseType.OK))
        dialog.set_current_folder(self.last_dir)
        ret = dialog.run()
        file_path = dialog.get_filename() if ret == Gtk.ResponseType.OK else None
        dialog.destroy()
        if file_path is not None:
            self.last_dir = os.path.dirname(file_path)
        return file_path


    def set_image_display_mode(self, model, display_mode):
        self.image_display_mode = display_mode
        self.display_image(model)
示例#32
0
文件: main.py 项目: insted/testowe_1
class wykres_1(Gtk.Window, pomiar):
    
    def __init__(self):    
        pomiar.__init__(self)
        Gtk.Window.__init__(self, title="Okno Pomiarowe")
        self.vpaned = Gtk.VPaned()     
        self.set_default_size(800,600)
        #self.move(200,100)     
        self.vbox = Gtk.VBox()
        self.box = Gtk.Box(spacing=6)
        self.set_border_width(20)
        
        self.button = Gtk.Button(label="Pomiar Amoniaku")
        self.button.connect("clicked", self.on_pomiar_clicked)
        self.box.pack_start(self.button, True, True, 5)
        
        self.button = Gtk.Button(label = "Pomiar Wody" )
        self.button.connect("clicked", self.on_pomiar_clicked)
        self.box.pack_start(self.button, True, True, 5)
        
        self.button = Gtk.Button(label = "Pomiar Temperatury" ) 
        self.button.connect("clicked", self.on_pomiar_clicked)
        self.box.pack_start(self.button,True, True, 5)  
        
        self.i = datetime.datetime.now()
        #self.i_strip = datetime.datetime.now().strftime("%y-%m-%d-%H-%M-%S")
        self.x = [date2num(self.i)] 
        print("Data teraz: ")
        print(self.x)
        
        self.f = plt.figure()
        self.f.autofmt_xdate()
        self.a = self.f.add_subplot(3,1,1)
        n1 = pomiar()
        self.amn_1 = n1.amoniak()
        self.wda_1 = n1.woda()
        self.tmp_1 = n1.temperatura()
        # print("Tutaj:",  z) 
        #print(type(z))
        #self.p = float(z)
        #print(self.p)
        self.a.plot_date(self.x, self.amn_1, tz=None,
                                color='green', linestyle = ':',
                                marker='o', markerfacecolor='blue', 
                                markersize=2)
           
        
        self.a.grid(True)
        #self.a.set_xlim(-3,22)
        self.a.set_ylim(-1,20)
        self.a.set_xlabel('Czas')
        self.a.set_ylabel('Amoniak [ppm]')
        self.b = self.f.add_subplot(312)
        self.b.plot_date(self.x,self.wda_1, tz=None,
                                color='green', linestyle = ':',
                                marker='o', markerfacecolor='blue', 
                                markersize=2)
        self.b.grid(True)
        self.b.set_xlabel('Czas')
        self.b.set_ylabel('Woda [ppm]')
        #self.a.set_animated(True)
        xfmt = md.DateFormatter('%m-%d-%H:%M:%S')    
        #print(xfmt)
        
        self.c = self.f.add_subplot(313)
        self.c.plot_date(self.x,self.tmp_1,tz=None,
                                color='green', linestyle = ':',
                                marker='o', markerfacecolor='blue', 
                                markersize=2)   
        self.c.grid(True)
        #self.a.set_xlim(-3,22)
        self.c.set_ylim(20,23)
        self.c.set_xlabel('Czas')
        self.c.set_ylabel(u'Temperatura [\u00B0C]')
        #self.c.set_xlim(0,self.x)
        plt.setp(self.c.xaxis.set_major_formatter(xfmt))
        #plt.setp(self.c.xaxis.get_majorticklabels(), rotation=30)
        plt.setp(self.a.xaxis.set_major_formatter(xfmt))
        # plt.setp(self.a.xaxis.get_majorticklabels(), rotation=30)
        plt.setp(self.b.xaxis.set_major_formatter(xfmt))
        #plt.setp(self.b.xaxis.set_major_locator(md.HourLocator()))
        plt.setp(self.a.xaxis.set_major_locator(MaxNLocator(4)))
        plt.setp(self.b.xaxis.set_major_locator(MaxNLocator(4)))
        plt.setp(self.c.xaxis.set_major_locator(MaxNLocator(4)))
        #self.c.relim()
#         relim()
        #self.c.autoscale_view()
        #plt.gcf()
        #plt.ion()
        # plt.setp(self.b.xaxis.get_majorticklabels(), rotation=30)
        
        #self.b.subplot_adjust(bottom = 0.5)
# Add canvas to vbox
        self.canvas = FigureCanvas(self.f)  # a Gtk.DrawingArea
        self.vbox.pack_start(self.canvas, True, True, 5)
       
# Create toolbar
        self.toolbar = NavigationToolbar(self.canvas,self)
        self.vbox.pack_start(self.toolbar, False, False, 5)
        
        self.add(self.vpaned)
        self.vpaned.add(self.box)
        self.vpaned.add(self.vbox)
        self.show_all()
        self.s = GObject.timeout_add(6000,self.wykres)
        #GObject.idle_add(self.wykres)
    def on_pomiar_clicked(self,button):
        print("Dziala")
        stop = ("7B49080000EA4A7D")
        stop_d = stop.decode("hex")
        print(stop_d)
        ser.close()
        ser.open()
        ser.flushInput()
        ser.flushOutput()
        ser.write(stop_d)
        GObject.source_remove(self.s)
        self.destroy()

    def wykres(self):
        i_1 = datetime.datetime.now()
        #i_strip = datetime.datetime.now().strftime("%y-%m-%d-%H-%M-%S")
            
        #print("Czas datetime" )
        #print(i_1)    
        x1 = [date2num(i_1)]    
        print("Czas teraz: ") 
        print(x1)   
        nowy_pomiar = pomiar()
        #print("Czas kiedys: " )
        print(self.x)
        amon_1 = nowy_pomiar.amoniak()
        tmp = nowy_pomiar.temperatura()
        wda = nowy_pomiar.woda()
        amoniak = ("Pomiar amoniaku: " + amon_1 + " \t " + "Woda: " + wda +
                    " \t " + "Temperatura celi: " + tmp )
        z = str(amoniak)
        self.set_title(z)
        self.a.plot_date(x1,amon_1,tz = None,
                                color='green', linestyle = '-',
                                marker='o', markerfacecolor='blue', 
                                markersize=3)
        self.b = self.f.add_subplot(312)
        self.b.plot_date(x1,wda, tz=None,
                                color='green', linestyle = ':',
                                marker='o', markerfacecolor='blue', 
                                markersize=3)
           
        
        self.b.grid(True)
       
        self.b.set_xlabel('Czas')
        self.b.set_ylabel('Woda [ppm]')
        self.c = self.f.add_subplot(313)
        
        self.c.plot_date(x1,tmp,tz=None,
                                color='green', linestyle = ':',
                                marker='o', markerfacecolor='blue', 
                                markersize=3 )
                                   
        self.c.grid(True)
        #self.a.set_xlim(-3,22)
        self.c.set_ylim(5,55)
        self.c.set_xlabel('Czas')
        self.c.set_ylabel(u'Temperatura [\u00B0C]')  
        self.a.set_xlim((i_1 - timedelta(minutes=8), i_1 + timedelta(seconds=15)) )   
        self.b.set_xlim((i_1 - timedelta(minutes=8), i_1 + timedelta(seconds=15)) )
        self.c.set_xlim((i_1 - timedelta(minutes=8), i_1 + timedelta(seconds=15)) ) 
        #self.a.xticks(x1,i_1,rotation=45)    
        # self.a.xaxis.set_minor_formatter(dates.DateFormatter('%d%a'))
        #self.a.setp(rotation=30)
        time.sleep(1)
        self.canvas.draw()   
        #self.show_all() 
        return True       
示例#33
0
class Ui():
    def __init__(self, profile):
        self.profile = profile
        self.builder = Gtk.Builder()
        prog_path = Path(__file__).parent
        self.builder.add_from_file(str(prog_path / 'ui.glade'))
        self.builder.connect_signals(self)
        for obj in self.builder.get_objects():
            try:
                setattr(self, Gtk.Buildable.get_name(obj), obj)
            except:
                pass
        self.f = Figure()
        self.canvas = FigureCanvas(self.f)
        self.figure_holder.pack_start(self.canvas, True, True, 5)
        self.profile_data_x = [0]
        self.profile_data_y = [25]
        for (rate, target, time) in self.profile:
            t = (target - self.profile_data_y[-1]) / rate
            self.profile_data_x.append(self.profile_data_x[-1] + t)
            self.profile_data_y.append(target)
            self.profile_data_x.append(self.profile_data_x[-1] + time)
            self.profile_data_y.append(target)
        self.recorded_data_x = [0]
        self.recorded_data_y = [25]
        self.replot()
        self.stop_button.set_sensitive(False)
        self.start_button.set_sensitive(False)
        print(self.connect_button.get_label())
        self.main_window.show_all()
        self.oven = None
        self.running = False
        self.start_t = None
        GLib.idle_add(lambda: self.idle())

    def quit(self, *args):
        if self.oven:
            self.oven.stop()
        exit()

    def idle(self):
        if self.oven:
            t = self.oven.process()
            if isinstance(t, float):
                if self.running:
                    self.recorded_data_x.append(time.time() - self.start_t)
                    self.recorded_data_y.append(t)
                else:
                    self.recorded_data_x = [0]
                    self.recorded_data_y = [t]
                self.replot()
        return True

    def replot(self):
        self.f.clear()
        ax = self.f.add_subplot(1, 1, 1)
        ax.plot(self.profile_data_x, self.profile_data_y)
        ax.plot(self.recorded_data_x, self.recorded_data_y, 'x')
        self.canvas.draw()

    def connect_clicked(self, *args):
        if self.oven is None:
            try:
                self.oven = oven.Oven(self.tty_entry.get_text())
            except:
                d = Gtk.MessageDialog(
                    self.main_window, 0, Gtk.MessageType.ERROR,
                    Gtk.ButtonsType.OK,
                    "Could not open tty {}".format(self.tty_entry.get_text()))
                d.run()
                d.destroy()
                import traceback
                traceback.print_exc()
                return
            self.connect_button.set_label('gtk-disconnect')
            self.start_button.set_sensitive(True)

        else:
            self.oven.stop()
            self.oven = None
            self.connect_button.set_label('gtk-connect')
            self.start_button.set_sensitive(False)
            self.stop_button.set_sensitive(False)

    def start_clicked(self, *args):
        if self.oven.start(self.profile):
            self.start_t = time.time()
            self.running = True
            self.start_button.set_sensitive(False)
            self.stop_button.set_sensitive(True)

    def stop_clicked(self, *args):
        self.oven.stop()
        self.running = False
        self.start_button.set_sensitive(True)
        self.stop_button.set_sensitive(False)
示例#34
0
class MainWindow(object):
    """Clase manejadora de la ventana principal.

    """
    def __init__(self):

        self.builder = Gtk.Builder()
        self.builder.set_translation_domain(LANG_DOM)
        self.builder.add_from_file(UI_FILE)
        self.builder.connect_signals(self)
        self.win=self.builder.get_object('window1')
        self.graf_box=self.builder.get_object('graf_box')
        self.statusbar = self.builder.get_object('statusbar')
        self.statusbar.push(1,_('Last access: '))
        self.ui_label={}
        for label in labels:
            self.ui_label[label]=self.builder.get_object(label)

        fig = Figure()
        self.plot1 = fig.add_subplot(111)
        self.plot2 = fig.add_subplot(212)
        self.plot3 = fig.add_subplot(313)
        self.plot3.set_position([0.055,0.06,0.93,0.24])
        self.plot2.set_position([0.055,0.38,0.93,0.24])
        self.plot1.set_position([0.055,0.69,0.93,0.24])
        self.canvas = FigureCanvas(fig)
        self.graf_box.pack_start(self.canvas,True,True,0)

        self.win.show_all()
        if self.get_params():
            self.update_ui()
            GObject.timeout_add_seconds(180,self.update_ui)

    def get_params(self):
        #Obtener parametros de programa
        params=DataStore.ParamStore(APP_DIR,PARAM_FILE)
        self.dir_data=params.get('paths','dir_data')
        if self.dir_data==None:
            dialog = Gtk.FileChooserDialog(_("Select pywws data folder:"), self.win,
                     Gtk.FileChooserAction.SELECT_FOLDER,
                    (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,Gtk.STOCK_OK, Gtk.ResponseType.OK))
            response = dialog.run()
            if response == Gtk.ResponseType.OK:
                self.dir_data = dialog.get_filename()
                params.set('paths','dir_data',self.dir_data)
                params.flush()
            else:
                self.dir_data=''
            dialog.destroy()
        if not os.path.exists(self.dir_data):
            dialog = Gtk.MessageDialog(self.win,0, Gtk.MessageType.ERROR,Gtk.ButtonsType.CANCEL,
                     _("pywws data folder does not exist."))
            dialog.run()
            dialog.destroy()
            return False
        return True

    def update_ui(self):
        self.statusbar.pop(1)
        pywws_data=get_pywws_data(self.dir_data)
        if pywws_data==None:
            self.statusbar.push(1,_('Error accessing pywws data.'))
            return True
        idx=pywws_data['a']['idx'].replace(tzinfo=TimeZone.utc).astimezone(TimeZone.Local)
        self.statusbar.push(1,_('Last access: ')+idx.strftime('%c').decode('utf-8'))
        for label in labels:
            tipo_k,pywws_k,strfmt=_parse_label(label)
            self.ui_label[label].set_label(strfmt.format(pywws_data[tipo_k][pywws_k]))
        #plotting
        val=[],[],[],[],[],[],[]
        for d in pywws_data['g']:
            val[0].append(d['idx'])
            val[1].append(d['temp_out'])
            val[2].append(d['temp_in'])
            val[3].append(d['hum_out'])
            val[4].append(d['hum_in'])
        for d in pywws_data['h']:
            val[5].append(d['idx'])
            val[6].append(d['rain'])
        self.plot1.clear()
        self.plot2.clear()
        self.plot3.clear()
        self.plot1.plot(val[0],val[1],label=_('Outdoor Temp.'))
        self.plot1.plot(val[0],val[2],label=_('Indoor Temp.'))
        self.plot2.plot(val[0],val[3],label=_('Outdoor Hum.'),color='red')
        self.plot2.plot(val[0],val[4],label=_('Indoor Hum.'),color='magenta')
        self.plot3.plot(val[5],val[6],label=_('Rain'))
        self.plot1.set_title(_('Last 24 hours.'),fontsize=10)
        self.plot1.set_ylabel(_('ᴼC'),fontsize=10)
        self.plot2.set_ylabel(_('%'),fontsize=10)
        self.plot3.set_ylabel(_('mm'),fontsize=10)
        for plot in (self.plot1,self.plot2,self.plot3):
            plot.tick_params(labelsize=9)
            plot.xaxis.set_major_formatter(dates.DateFormatter('%H:%M',TimeZone.Local))
            plot.xaxis.set_major_locator(dates.HourLocator())
            plot.grid(True)
            plot.legend(loc='best',prop={'size':10})
        self.canvas.draw()
        return True

    def on_window_destroy(self,win):
        Gtk.main_quit()

    def run(self):
        Gtk.main()