Beispiel #1
0
def main():
    args = get_argparser().parse_args()
    common_args.init_logger_from_args(args)

    loop = asyncio.get_event_loop()
    try:
        get_logs_task = asyncio.ensure_future(
            get_logs_sim(args.core_addr) if args.
            simulation else get_logs(args.core_addr))
        try:
            server = Server({"corelog": PingTarget()}, None, True)
            loop.run_until_complete(
                server.start(common_args.bind_address_from_args(args),
                             args.port))
            try:
                loop.run_until_complete(server.wait_terminate())
            finally:
                loop.run_until_complete(server.stop())
        finally:
            get_logs_task.cancel()
            try:
                loop.run_until_complete(get_logs_task)
            except asyncio.CancelledError:
                pass
    finally:
        loop.close()
Beispiel #2
0
def main():
    args = get_argparser().parse_args()
    common_args.init_logger_from_args(args)

    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    try:
        signal_handler = SignalHandler()
        signal_handler.setup()
        try:
            get_logs_task = asyncio.ensure_future(
                get_logs_sim(args.core_addr) if args.simulation else get_logs(args.core_addr))
            try:
                server = Server({"corelog": PingTarget()}, None, True)
                loop.run_until_complete(server.start(common_args.bind_address_from_args(args), args.port))
                try:
                    _, pending = loop.run_until_complete(asyncio.wait(
                        [signal_handler.wait_terminate(),
                         server.wait_terminate(),
                         get_logs_task],
                        return_when=asyncio.FIRST_COMPLETED))
                    for task in pending:
                        task.cancel()
                finally:
                    loop.run_until_complete(server.stop())
            finally:
                pass
        finally:
            signal_handler.teardown()
    finally:
        loop.close()
Beispiel #3
0
def main():
    args = get_argparser().parse_args()
    common_args.init_logger_from_args(args)

    bind_address = common_args.bind_address_from_args(args)

    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    try:
        signal_handler = SignalHandler()
        signal_handler.setup()
        try:
            monitor_mux = MonitorMux()
            comm_moninj = CommMonInj(monitor_mux.monitor_cb,
                                     monitor_mux.injection_status_cb,
                                     monitor_mux.disconnect_cb)
            monitor_mux.comm_moninj = comm_moninj
            loop.run_until_complete(comm_moninj.connect(args.core_addr))
            try:
                proxy_server = ProxyServer(monitor_mux)
                loop.run_until_complete(proxy_server.start(bind_address, args.port_proxy))
                try:
                    server = Server({"moninj_proxy": PingTarget()}, None, True)
                    loop.run_until_complete(server.start(bind_address, args.port_control))
                    try:
                        _, pending = loop.run_until_complete(asyncio.wait(
                            [signal_handler.wait_terminate(),
                             server.wait_terminate(),
                             comm_moninj.wait_terminate()],
                            return_when=asyncio.FIRST_COMPLETED))
                        for task in pending:
                            task.cancel()
                    finally:
                        loop.run_until_complete(server.stop())
                finally:
                    loop.run_until_complete(proxy_server.stop())
            finally:
                loop.run_until_complete(comm_moninj.close())
        finally:
            signal_handler.teardown()
    finally:
        loop.close()
Beispiel #4
0
class PMTReadoutDock(QtWidgets.QDockWidget):
    def __init__(self, acxn):
        QtWidgets.QDockWidget.__init__(self, "PMT Readout")
        self.acxn = acxn
        self.cxn = None
        self.p = None
        try:
            self.cxn = labrad.connect()
            self.p = self.cxn.parametervault
        except:
            logger.error("Failed to initially connect to labrad.",
                         exc_info=True)
            self.setDisabled(True)
        self.current_line = 0
        self.number_lines = 0
        self.hist = None
        self.setObjectName("PMTReadoutHistogram")
        self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable
                         | QtWidgets.QDockWidget.DockWidgetFloatable)
        self.main_widget = QtWidgets.QWidget()
        self.setWidget(self.main_widget)
        self.make_GUI()
        self.connect_GUI()
        self.connect_asyncio_server()

    def save_state(self):
        pass

    def restore_state(self):
        pass

    def connect_asyncio_server(self):
        self.loop = asyncio.get_event_loop()
        self.asyncio_server = Server(
            {"pmt_histogram": self.RemotePlotting(self)}, None, True)
        self.task = self.loop.create_task(
            self.asyncio_server.start("::1", 3287))

    class RemotePlotting:
        def __init__(self, hist):
            self.hist = hist

        def plot(self, data):
            if self.hist.hist is not None:
                for bar in self.hist.hist:
                    try:
                        bar.remove()
                    except ValueError as e:
                        continue
            _, _, self.hist.hist = self.hist.ax.hist(data,
                                                     bins=35,
                                                     histtype="bar",
                                                     rwidth=1,
                                                     edgecolor="k",
                                                     linewidth=1.2)
            self.hist.canvas.draw()
            self.hist.ax.autoscale(enable=True, axis="both")
            self.hist.ax.set_xlim(left=0)
            self.hist.ax.relim()

    def closeEvent(self, event):
        self.task.cancel()
        self.loop.create_task(self.asyncio_server.stop())
        super(PMTReadoutDock, self).closeEvent(event)

    def make_GUI(self):
        layout = QtWidgets.QGridLayout()

        self.fig = Figure()
        self.fig.patch.set_facecolor((.97, .96, .96))
        self.canvas = FigureCanvasQTAgg(self.fig)
        self.canvas.setParent(self)
        self.ax = self.fig.add_subplot(111)
        self.ax.set_ylim((0, 50))
        self.ax.set_xlim((0, 100))
        self.ax.set_facecolor((.97, .96, .96))
        self.ax.tick_params(top=False,
                            bottom=False,
                            left=False,
                            right=False,
                            labeltop=True,
                            labelbottom=True,
                            labelleft=True,
                            labelright=True)
        self.mpl_toolbar = NavigationToolbar2QT(self.canvas, self)
        self.fig.tight_layout()
        self.canvas.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
                                  QtWidgets.QSizePolicy.Expanding)
        self.ax.tick_params(axis="both", direction="in")

        self.n_thresholds = None
        self.curr_threshold = None
        if self.p:
            lines = self.p.get_parameter(["StateReadout", "threshold_list"])
            slines = sorted(lines)
            if not list(slines) == list(lines):
                self.p.set_parameter(
                    ["StateReadout", "threshold_list", slines])
                lines = slines
            self.number_lines = len(lines)
            self.lines = [
                self.ax.axvline(line, lw=3, color="r") for line in lines
            ]
            self.n_thresholds = QtWidgets.QSpinBox()
            self.n_thresholds.setValue(len(lines))
            self.n_thresholds.setMinimum(1)
            self.n_thresholds.setMaximum(10)
            self.curr_threshold = QtWidgets.QSpinBox()
            self.curr_threshold.setValue(1)
            self.curr_threshold.setMinimum(1)
            self.curr_threshold.setMaximum(len(lines))

            layout.addWidget(self.mpl_toolbar, 0, 0)
            layout.addWidget(QtWidgets.QLabel("no. thresholds: "), 0, 1)
            layout.addWidget(self.n_thresholds, 0, 2)
            layout.addWidget(QtWidgets.QLabel("select threshold: "), 0, 3)
            layout.addWidget(self.curr_threshold, 0, 4)

        layout.addWidget(self.canvas, 1, 0, 1, 5)
        self.main_widget.setLayout(layout)

        if self.cxn:
            self.cxn.disconnect()

    def connect_GUI(self):
        self.canvas.mpl_connect("button_press_event", self.on_click)
        if self.n_thresholds:
            self.n_thresholds.valueChanged.connect(self.n_thresholds_changed)
        if self.curr_threshold:
            self.curr_threshold.valueChanged.connect(
                self.curr_threshold_changed)

    @inlineCallbacks
    def n_thresholds_changed(self, val):
        p = yield self.acxn.get_server("ParameterVault")
        self.curr_threshold.setMaximum(int(val))
        diff = val - self.number_lines
        self.number_lines = val
        if diff < 0:
            for _ in range(abs(diff)):
                l = self.lines.pop()
                l.remove()
                del l
                self.canvas.draw()
            tlist = yield p.get_parameter(["StateReadout", "threshold_list"])
            tlist = tlist[:diff]
            yield p.set_parameter(["StateReadout", "threshold_list", tlist])

        if diff > 0:
            for _ in range(diff):
                tlist = yield p.get_parameter(
                    ["StateReadout", "threshold_list"])
                maxt = max(tlist)
                tlist = np.append(tlist, maxt + 2)
                self.lines.append(self.ax.axvline(maxt + 2, lw=3, color="r"))
                yield p.set_parameter(
                    ["StateReadout", "threshold_list", tlist])
                self.canvas.draw()

    def curr_threshold_changed(self, val):
        self.current_line = int(val) - 1

    @inlineCallbacks
    def on_click(self, event):
        p = yield self.acxn.get_server("ParameterVault")
        if type(event.button) == int and not event.xdata is None:
            xval = int(round(event.xdata))
            idx = self.current_line
            tlist = yield p.get_parameter(["StateReadout", "threshold_list"])
            tlist = tlist
            tlist[idx] = xval
            if idx > 0:
                if tlist[idx - 1] >= tlist[idx]:
                    return
            if idx < len(tlist) - 1:
                if tlist[idx] >= tlist[idx + 1]:
                    return
            yield p.set_parameter(["StateReadout", "threshold_list", tlist])
class PulseSequenceVisualizer(QtWidgets.QDockWidget):
    def __init__(self):
        QtWidgets.QDockWidget.__init__(self, "Pulse Sequence")
        self.setObjectName("PulseSequenceDock")
        self.setFeatures(QtWidgets.QDockWidget.NoDockWidgetFeatures)
        # Initialize
        self.last_seq_data = None
        self.last_plot = None
        self.subscribed = False
        self.current_box = None
        self.mpl_connection = None
        self.main_widget = QtWidgets.QWidget()
        self.setWidget(self.main_widget)
        self.create_layout()
        self.connect_asyncio_server()

    def connect_asyncio_server(self):
        self.loop = asyncio.get_event_loop()
        self.asyncio_server = Server(
            {
                "pulse_sequence_visualizer":
                PulseSequenceVisualizerServer(self),
                "simulation_logger": simulation_logger
            }, None, True)
        self.task = self.loop.create_task(
            self.asyncio_server.start("::1", 3289))

    def create_layout(self):
        # Creates GUI layout
        layout = QtGui.QVBoxLayout()
        plot_layout = self.create_plot_layout()
        layout.addLayout(plot_layout)
        self.main_widget.setLayout(layout)

    def create_plot_layout(self):
        # Creates empty matplotlib plot layout
        layout = QtGui.QVBoxLayout()
        self.fig = Figure()
        self.canvas = FigureCanvas(self.fig)
        self.canvas.setParent(self)
        self.axes = self.fig.add_subplot(111)
        self.axes.legend(loc='best')
        self.mpl_toolbar = NavigationToolbar(self.canvas, self)
        self.axes.set_title('Most Recent Pulse Sequence', fontsize=22)
        self.axes.set_xlabel('Time (ms)')
        self.fig.tight_layout()
        # Create an empty an invisible annotation, which will be moved around and set to visible later when needed
        self.annot = self.axes.annotate("",
                                        xy=(0, 0),
                                        xytext=(-0.5, 0.5),
                                        textcoords="offset points",
                                        bbox=dict(boxstyle="round", fc="w"),
                                        horizontalalignment='center',
                                        multialignment='left',
                                        verticalalignment='center')
        self.annot.get_bbox_patch().set_alpha(0.8)
        self.annot.set_visible(False)
        # Add the canvas to the GUI widget.
        layout.addWidget(self.mpl_toolbar)
        layout.addWidget(self.canvas)
        return layout

    def on_new_seq(self, dds, ttl, channels, signal_time):
        # Temporary stop tracking mouse movement
        if self.mpl_connection:
            self.canvas.mpl_disconnect(self.mpl_connection)
        self.last_seq_data = {'DDS': dds, 'TTL': ttl, 'channels': channels}
        # Create SequenceAnalyzer object instance
        self.sequence = SequenceAnalyzer(ttl, dds, channels)
        # Clear the plot of all drawn objects
        self.clear_plot()
        # Call the SequenceAnalyzer object's create_full_plot method to draw the plot on the GUI's axes.
        self.sequence.create_full_plot(self.axes)
        self.axes.set_title('Most Recent Pulse Sequence, ' +
                            time.strftime('%Y-%m-%d %H:%M:%S', signal_time))
        # Draw and reconnect to mouse hover events
        self.canvas.draw_idle()
        self.mpl_connection = self.canvas.mpl_connect("motion_notify_event",
                                                      self.hover)

    def clear_plot(self):
        # Remove all lines, boxes, and annotations, except for the hover annotation
        for child in self.axes.get_children():
            if isinstance(child,
                          (matplotlib.lines.Line2D, matplotlib.text.Annotation,
                           matplotlib.collections.PolyCollection)):
                if child is not self.annot:
                    child.remove()

    def format_starttime(self, t):
        # Function for formatting times in the hover annotation
        if round(1e6 * t) < 1000:
            return '{:.1f} $\mu$s'.format(1e6 * t)
        else:
            return '{:.3f} ms'.format(1e3 * t)

    def format_duration(self, t):
        # Function for formatting times in the hover annotation
        if round(1e6 * t) < 1000:
            return '%#.4g $\mu$s' % (1e6 * t)
        else:
            return '%#.4g ms' % (1e3 * t)

    def update_annot(self, dds_box):
        # This function updates the text of the hover annotation.
        drawx = 1e3 * (dds_box.starttime() + dds_box.duration() / 2.0)
        drawy = dds_box.offset + dds_box.scale / 2.0
        self.annot.xy = (drawx, drawy)
        text = '{0}\nStart: {1}\nDuration: {2}\n{3:.4f} MHz\n{4:.2f} amp w/att'.format(
            dds_box.channel, self.format_starttime(dds_box.starttime()),
            self.format_duration(dds_box.duration()), dds_box.frequency(),
            dds_box.amplitude())
        self.annot.set_text(text)

    def hover(self, event):
        # This function is called when the mouse moves
        # It updates the hover annotation if necessary.
        (self.last_mouse_x, self.last_mouse_y) = (event.x, event.y)
        vis = self.annot.get_visible()
        if event.inaxes == self.axes:
            for dds_box in self.sequence.dds_boxes:
                if dds_box.box.contains(event)[0]:
                    if dds_box is not self.current_box:
                        self.current_box = dds_box
                        self.update_annot(dds_box)
                        self.annot.set_visible(True)
                        self.canvas.draw_idle()
                    break
                else:
                    self.current_box = None
                    if vis:
                        self.annot.set_visible(False)
                        self.canvas.draw_idle()
        else:
            self.current_box = None

    def closeEvent(self, event):
        self.loop.create_task(self.asyncio_server.stop())
        super(PulseSequenceVisualizer, self).closeEvent(event)
    def main(extra_args=None):
        logging.getLogger(name).info("Launching controller %s", name)

        def get_argparser():
            parser = argparse.ArgumentParser(
                description="Generic controller for {}".format(name))
            group = parser.add_argument_group(name)
            group.add_argument(
                "--id",
                required=True,
                type=str,
                help=
                "VISA id to connect to. This Controller will obtain an exclusive lock.",
            )
            group.add_argument(
                "--simulation",
                action="store_true",
                help=
                "Run this controller in simulation mode. ID will be ignored but is still required.",
            )
            common_args.simple_network_args(parser, default_port)
            common_args.verbosity_args(parser)

            return parser

        args = get_argparser().parse_args(extra_args)
        common_args.init_logger_from_args(args)

        driver_obj = driver_class(None,
                                  id=args.id,
                                  simulation=args.simulation,
                                  **driver_kwargs)

        loop = asyncio.get_event_loop()

        # Start an ARTIQ server for this device.
        #
        # Allow parallel connections so that functions which don't touch the
        # serial device can be done simultaneously: functions which do are
        # protected by @with_lock.
        server = Server(
            {name: driver_obj},
            description="An automatically generated server for {}".format(
                driver_class.__name__),
            builtin_terminate=True,
            allow_parallel=True,
        )

        loop.run_until_complete(
            server.start(
                host=common_args.bind_address_from_args(args),
                port=args.port,
            ))

        try:
            loop.run_until_complete(server.wait_terminate())
        finally:
            try:
                loop.run_until_complete(server.stop())
            finally:
                # Close the VISA connection after the server has shutdown
                driver_obj.close()

            loop.close()
Beispiel #7
0
class CameraReadoutDock(QtWidgets.QDockWidget):
    def __init__(self, acxn):
        QtWidgets.QDockWidget.__init__(self, "Camera Readout")
        self.acxn = acxn
        self.setObjectName("CameraReadoutHistogram")
        self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable
                         | QtWidgets.QDockWidget.DockWidgetFloatable)
        self.image = None
        self.image_region = None
        self.run_time = None
        self.main_widget = QtWidgets.QWidget()
        self.setWidget(self.main_widget)
        self.make_GUI()
        self.connect_GUI()
        self.connect_asyncio_server()

    def connect_asyncio_server(self):
        self.loop = asyncio.get_event_loop()
        self.asyncio_server = Server(
            {"camera_reference_image": self.RemotePlotting(self)}, None, True)
        self.task = self.loop.create_task(
            self.asyncio_server.start("::1", 3288))

    class RemotePlotting:
        def __init__(self, plt):
            self.plt = plt

        def plot(self, image, image_region, run_time=None):
            self.plt.image = image
            self.plt.image_region = image_region
            if run_time is None:
                self.run_time = dt.now().strftime("%Y%m%d_%H%M.%S")
            try:
                cxn = labrad.connect()
                p = cxn.parametervault
            except:
                logger.error("Couldn't connect to parametervault",
                             exc_info=True)
            N = int(p.get_parameter("IonsOnCamera", "ion_number"))
            x_axis = np.arange(image_region[2], image_region[3] + 1,
                               image_region[0])
            y_axis = np.arange(image_region[4], image_region[5] + 1,
                               image_region[1])
            xx, yy = np.meshgrid(x_axis, y_axis)

            fitter = ion_state_detector(N)
            result, params = fitter.guess_parameters_and_fit(xx, yy, image)
            p.set_parameter("IonsOnCamera", "fit_background_level",
                            params["background_level"].value)
            p.set_parameter("IonsOnCamera", "fit_amplitude",
                            params["amplitude"].value)
            p.set_parameter("IonsOnCamera", "fit_rotation_angle",
                            params["rotation_angle"].value)
            p.set_parameter("IonsOnCamera", "fit_center_horizontal",
                            params["center_x"].value)
            p.set_parameter("IonsOnCamera", "fit_center_vertical",
                            params["center_y"].value)
            p.set_parameter("IonsOnCamera", "fit_spacing",
                            params["spacing"].value)
            p.set_parameter("IonsOnCamera", "fit_sigma", params["sigma"].value)

            self.plt.ax.clear()
            with suppress(Exception):
                self.plt.cb.remove()
            I = self.plt.ax.imshow(image,
                                   cmap="cividis",
                                   interpolation="spline16",
                                   extent=[
                                       x_axis.min(),
                                       x_axis.max(),
                                       y_axis.max(),
                                       y_axis.min()
                                   ])
            self.plt.cb = self.plt.fig.colorbar(I, fraction=0.046, pad=0.04)
            x_axis_fit = np.linspace(x_axis.min(), x_axis.max(),
                                     x_axis.size * 10)
            y_axis_fit = np.linspace(y_axis.min(), y_axis.max(),
                                     y_axis.size * 10)
            xx, yy = np.meshgrid(x_axis_fit, y_axis_fit)
            fit = fitter.ion_model(params, xx, yy)
            self.plt.ax.contour(x_axis_fit,
                                y_axis_fit,
                                fit,
                                3,
                                colors=[(1., .49, 0., .75)])

            if result is not None:
                # print(lmfit.fit_report(result, show_correl=False))
                results_text = lmfit.fit_report(result, show_correl=False)
                param_results = results_text.split("\n")[-7:]
                for i, param_result in enumerate(param_results):
                    param_result = param_result.split("(")[0]
                    param_result = param_result.replace(" +/- ", "(")[:-1]
                    param_result = param_result.split(".")
                    param_result1 = param_result[1].split("(")
                    param_result[1] = param_result1[0][:3] + "("
                    try:
                        param_result[2] = param_result[2][:3]
                    except IndexError:
                        pass
                    param_result = ".".join(param_result)
                    param_result += ")"
                    param_results[i] = param_result
                results_text = "\n".join(param_results)
                results_text += "\n    chi_red = {:.2f}".format(result.redchi)
                results_text += "\n    runtime = " + str(self.run_time)
                self.plt.ax.annotate(results_text, (0.5, 0.75),
                                     xycoords="axes fraction",
                                     color=(1., .49, 0., 1.))

            self.plt.canvas.draw()
            self.plt.ax.relim()
            self.plt.ax.autoscale(enable=True, axis="both")

            cxn.disconnect()

        def enable_button(self):
            self.plt.reference_image_button.setDisabled(False)

    def closeEvent(self, event):
        self.task.cancel()
        self.loop.create_task(self.asyncio_server.stop())
        super(CameraReadoutDock, self).closeEvent(event)

    def make_GUI(self):
        layout = QtWidgets.QGridLayout()

        self.fig = Figure(figsize=(10, 10), tight_layout=True)
        self.fig.patch.set_facecolor((.97, .96, .96))
        self.canvas = FigureCanvasQTAgg(self.fig)
        self.canvas.setParent(self)
        # self.canvas.setMinimumSize(800, 800)
        self.ax = self.fig.add_subplot(111)
        self.ax.set_facecolor((.97, .96, .96))
        self.ax.tick_params(top=False,
                            bottom=False,
                            left=False,
                            right=False,
                            labeltop=True,
                            labelbottom=True,
                            labelleft=True,
                            labelright=False)
        self.mpl_toolbar = NavigationToolbar2QT(self.canvas, self)
        self.canvas.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
                                  QtWidgets.QSizePolicy.Expanding)
        self.ax.tick_params(axis="both", direction="in")
        self.reference_image_button = QtWidgets.QPushButton("reference image")

        try:
            cxn = labrad.connect()
            p = cxn.parametervault
        except:
            pass
        accessed_params = set()
        parameters = p.get_parameter_names("IonsOnCamera")
        for parameter in parameters:
            accessed_params.update({"IonsOnCamera." + parameter})

        d_accessed_parameter_editor = ParameterEditorDock(
            acxn=None, name="Camera Options", accessed_params=accessed_params)
        d_accessed_parameter_editor.setFeatures(
            QtGui.QDockWidget.NoDockWidgetFeatures)
        d_accessed_parameter_editor.setTitleBarWidget(QtGui.QWidget())
        d_accessed_parameter_editor.table.setMaximumWidth(390)

        layout.addWidget(self.mpl_toolbar, 0, 0, 1, 1)
        layout.addWidget(self.reference_image_button, 0, 2, 1, 1)
        layout.addWidget(d_accessed_parameter_editor, 1, 0, 1, 1)
        layout.addWidget(self.canvas, 1, 1, 1, 2)

        self.main_widget.setLayout(layout)

    def connect_GUI(self):
        self.scheduler = Client("::1", 3251, "master_schedule")
        self.reference_image_button.clicked.connect(self.get_reference_image)

    def get_reference_image(self):
        self.reference_image_button.setDisabled(True)
        expid = {
            "arguments": {},
            "class_name": "ReferenceImage",
            "file": "misc/reference_image.py",
            "log_level": 30,
            "repo_rev": None,
            "priority": 2
        }
        self.scheduler.submit("main", expid, 2)

    def save_state(self):
        return {
            "image": self.image,
            "image_region": self.image_region,
            "run_time": self.run_time
        }

    def restore_state(self, state):
        if state["image"] is not None and state["image_region"] is not None:
            r = self.RemotePlotting(self)
            r.plot(state["image"],
                   state["image_region"],
                   run_time=state["run_time"])
Beispiel #8
0
class rcgDock(QDockWidgetCloseDetect):
    def __init__(self, main_window):
        QDockWidgetCloseDetect.__init__(self, "Real Complicated Grapher")
        self.setObjectName("RCG")
        self.main_window = main_window
        self.is_closed = False
        self.main_window.addDockWidget(QtCore.Qt.TopDockWidgetArea, self)
        self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable)
        self.setFloating(True)
        self.rcg = RCG()
        self.setWidget(self.rcg)
        self.setTitleBarWidget(QtWidgets.QMainWindow())
        self.top_level_changed()
        self.connect_server()

    def top_level_changed(self):
        if self.isFloating():
            self.setWindowFlags(QtCore.Qt.CustomizeWindowHint
                                | QtCore.Qt.Window
                                | QtCore.Qt.WindowMinimizeButtonHint
                                | QtCore.Qt.WindowMaximizeButtonHint
                                | QtCore.Qt.WindowCloseButtonHint)

    def connect_server(self):
        self.loop = asyncio.get_event_loop()
        self.server = Server({"rcg": self.RemotePlotting(self.rcg)}, None,
                             True)
        self.task = self.loop.create_task(
            self.server.start(conf.host, conf.port))

    def closeEvent(self, event):
        self.is_closed = True
        self.task.cancel()
        self.loop.create_task(self.server.stop())
        super(rcgDock, self).closeEvent(event)

    class RemotePlotting:
        def __init__(self, rcg):
            self.rcg = rcg

        def echo(self, mssg):
            return mssg

        def get_tab_index_from_name(self, name):
            return self.rcg.tabs[name]

        def plot(self,
                 x,
                 y,
                 tab_name="Current",
                 plot_name=None,
                 plot_title="new_plot",
                 append=False,
                 file_=None,
                 range_guess=None):
            if plot_name is None:
                # need to clean this up
                for tab, graph_configs in conf.tab_configs:
                    for gc in graph_configs:
                        if gc.name == tab_name:
                            plot_name = tab_name
                            tab_name = tab
                            break
            idx = self.rcg.tabs[tab_name]
            if type(x) is np.ndarray:
                x = x[~np.isnan(x)]
            if type(y) is np.ndarray:
                y = y[~np.isnan(y)]
            if (plot_title
                    in self.rcg.widget(idx).gw_dict[plot_name].items.keys()
                    and not append):
                i = 1
                while True:
                    try_plot_title = plot_title + str(i)
                    if try_plot_title not in self.rcg.widget(
                            idx).gw_dict[plot_name].items.keys():
                        plot_title = try_plot_title
                        break
                    else:
                        i += 1
            try:
                self.rcg.widget(idx).gw_dict[plot_name].add_plot_item(
                    plot_title,
                    x,
                    y,
                    append=append,
                    file_=file_,
                    range_guess=range_guess)
            except AttributeError:
                # curve not currently displayed on graph
                return

        def plot_from_file(self, file_, tab_name="Current", plot_name=None):
            if plot_name is None:
                plot_name = tab_name
            idx = self.rcg.tabs[tab_name]
            self.rcg.widget(idx).gw_dict[plot_name].upload_curve(file_=file_)