def main(): args = get_argparser().parse_args() common_args.init_logger_from_args(args) loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) atexit.register(loop.close) signal_handler = SignalHandler() signal_handler.setup() atexit.register(signal_handler.teardown) writer = DBWriter(args.baseurl_db, args.user_db, args.password_db, args.database, args.table) writer.start() atexit_register_coroutine(writer.stop) filter = Filter(args.pattern_file) rpc_server = Server({"influxdb_filter": filter}, builtin_terminate=True) loop.run_until_complete(rpc_server.start(common_args.bind_address_from_args(args), args.port_control)) atexit_register_coroutine(rpc_server.stop) reader = MasterReader(args.server_master, args.port_master, args.retry_master, filter._filter, writer) reader.start() atexit_register_coroutine(reader.stop) _, pending = loop.run_until_complete(asyncio.wait( [signal_handler.wait_terminate(), rpc_server.wait_terminate()], return_when=asyncio.FIRST_COMPLETED)) for task in pending: task.cancel()
def main(): args = get_argparser().parse_args() common_args.init_logger_from_args(args) loop = asyncio.get_event_loop() atexit.register(loop.close) writer = DBWriter(args.baseurl_db, args.user_db, args.password_db, args.database, args.table) writer.start() atexit_register_coroutine(writer.stop) log = Log(writer) server = Logger() rpc_server = Server({"schedule_logger": server}, builtin_terminate=True) loop.run_until_complete( rpc_server.start(common_args.bind_address_from_args(args), args.port_control)) atexit_register_coroutine(rpc_server.stop) reader = MasterReader(args.server_master, args.port_master, args.retry_master, log) reader.start() atexit_register_coroutine(reader.stop) loop.run_until_complete(rpc_server.wait_terminate())
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()
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()
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 main(): args = get_argparser().parse_args() root_logger = logging.getLogger() root_logger.setLevel(logging.NOTSET) source_adder = SourceFilter(logging.WARNING + args.quiet*10 - args.verbose*10, "ctlmgr({})".format(platform.node())) console_handler = logging.StreamHandler() console_handler.setFormatter(logging.Formatter( "%(levelname)s:%(source)s:%(name)s:%(message)s")) console_handler.addFilter(source_adder) root_logger.addHandler(console_handler) loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) atexit.register(loop.close) signal_handler = SignalHandler() signal_handler.setup() atexit.register(signal_handler.teardown) logfwd = LogForwarder(args.server, args.port_logging, args.retry_master) logfwd.addFilter(source_adder) root_logger.addHandler(logfwd) logfwd.start() atexit_register_coroutine(logfwd.stop) ctlmgr = ControllerManager(args.server, args.port_notify, args.retry_master, args.host_filter) ctlmgr.start() atexit_register_coroutine(ctlmgr.stop) class CtlMgrRPC: retry_now = ctlmgr.retry_now rpc_target = CtlMgrRPC() rpc_server = Server({"ctlmgr": rpc_target}, builtin_terminate=True) loop.run_until_complete(rpc_server.start(common_args.bind_address_from_args(args), args.port_control)) atexit_register_coroutine(rpc_server.stop) _, pending = loop.run_until_complete(asyncio.wait( [signal_handler.wait_terminate(), rpc_server.wait_terminate()], return_when=asyncio.FIRST_COMPLETED)) for task in pending: task.cancel()
async def run(): with await Shutter.connect(args.device, loop=loop) as dev: server = Server({"ptb_shutter": dev}, None, True) await server.start(bind_address_from_args(args), args.port) try: await server.wait_terminate() finally: await server.stop()
async def run(): async with RPCClient(NetworkConnection(args.device, loop=loop)) as dev: server = Server({"laser": dev}, None, True) await server.start(common_args.bind_address_from_args(args), args.port) try: await server.wait_terminate() finally: await server.stop()
def main(): args = get_argparser().parse_args() root_logger = logging.getLogger() root_logger.setLevel(logging.NOTSET) source_adder = SourceFilter(logging.WARNING + args.quiet*10 - args.verbose*10, "ctlmgr({})".format(platform.node())) console_handler = logging.StreamHandler() console_handler.setFormatter(logging.Formatter( "%(levelname)s:%(source)s:%(name)s:%(message)s")) console_handler.addFilter(source_adder) root_logger.addHandler(console_handler) if os.name == "nt": loop = asyncio.ProactorEventLoop() asyncio.set_event_loop(loop) else: loop = asyncio.get_event_loop() atexit.register(loop.close) logfwd = LogForwarder(args.server, args.port_logging, args.retry_master) logfwd.addFilter(source_adder) root_logger.addHandler(logfwd) logfwd.start() atexit_register_coroutine(logfwd.stop) ctlmgr = ControllerManager(args.server, args.port_notify, args.retry_master) ctlmgr.start() atexit_register_coroutine(ctlmgr.stop) class CtlMgrRPC: retry_now = ctlmgr.retry_now rpc_target = CtlMgrRPC() rpc_server = Server({"ctlmgr": rpc_target}, builtin_terminate=True) loop.run_until_complete(rpc_server.start(common_args.bind_address_from_args(args), args.port_control)) atexit_register_coroutine(rpc_server.stop) loop.run_until_complete(rpc_server.wait_terminate())
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()
async def run(): await dev.connect(args.uri, user=args.user, password=args.password) await dev.misc() server = Server({"oors": dev}, None, True) await server.start(bind_address_from_args(args), args.port) try: await server.wait_terminate() except KeyboardInterrupt: pass finally: await server.stop()
async def run(): with await Wavemeter.connect(args.device, port=args.device_port, loop=loop) as dev: # only wavemeter # logger.debug("connected, version %s", await dev.get_version()) server = Server({"wavemeter": dev}, None, True) await server.start(common_args.bind_address_from_args(args), args.port) try: await server.wait_terminate() finally: await server.stop()
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 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 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"])
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 WandServer: def __init__(self): self.args = args = get_argparser().parse_args() init_logger_from_args(args) self.config = load_config(args, "_server") self.lasers = self.config["lasers"].keys() for laser in self.lasers: self.config["lasers"][laser]["lock_ready"] = False # connect to hardware self.wlm = WLM(args.simulation) if self.config.get("osas", "wlm") != "wlm": self.osas = NiOSA(self.config["osas"], args.simulation) self.exp_min = self.wlm.get_exposure_min() self.exp_max = self.wlm.get_exposure_max() self.num_ccds = self.wlm.get_num_ccds() if self.config["switch"]["type"] == "internal": self.switch = self.wlm.get_switch() elif self.config["switch"]["type"] == "leoni": self.switch = LeoniSwitch( self.config["switch"]["ip"], args.simulation) else: raise ValueError("Unrecognised switch type: {}".format( self.config["switch"]["type"])) # measurement queue, processed by self.measurement_task self.measurement_ids = task_id_generator() self.measurements_queued = asyncio.Event() self.queue = [] self.wake_locks = {laser: asyncio.Event() for laser in self.lasers} # schedule initial frequency/osa readings all lasers self.measurements_queued.set() for laser in self.lasers: self.queue.append({ "laser": laser, "priority": 0, "expiry": time.time(), "id": next(self.measurement_ids), "get_osa_trace": True, "done": asyncio.Event() }) # "notify" interface self.laser_db = Notifier(self.config["lasers"]) self.freq_db = Notifier({laser: { "freq": None, "status": WLMMeasurementStatus.ERROR, "timestamp": 0 } for laser in self.lasers}) self.osa_db = Notifier({laser: { "trace": None, "timestamp": 0 } for laser in self.lasers}) self.server_notify = Publisher({ "laser_db": self.laser_db, # laser settings "freq_db": self.freq_db, # most recent frequency measurements "osa_db": self.osa_db # most recent osa traces }) # "control" interface self.control_interface = ControlInterface(self) self.server_control = RPCServer({"control": self.control_interface}, allow_parallel=True) self.running = False def start(self): """ Start the server """ self.executor = ThreadPoolExecutor(max_workers=2) self.loop = loop = asyncio.get_event_loop() atexit.register(loop.close) # start control server bind = bind_address_from_args(self.args) loop.run_until_complete( self.server_control.start(bind, self.args.port_control)) atexit_register_coroutine(self.server_control.stop) # start notify server loop.run_until_complete( self.server_notify.start(bind, self.args.port_notify)) atexit_register_coroutine(self.server_notify.stop) asyncio.ensure_future(self.measurement_task()) for laser in self.lasers: asyncio.ensure_future(self.lock_task(laser)) # backup of configuration file backup_config(self.args, "_server") asyncio.ensure_future(regular_config_backup(self.args, "_server")) atexit.register(backup_config, self.args, "_server") logger.info("server started") self.running = True loop.run_forever() async def lock_task(self, laser): conf = self.laser_db.raw_view[laser] # only try to lock lasers with a controller specified if not conf.get("host") or self.args.simulation: return while self.running: conf["lock_ready"] = False try: iface = DLPro(conf["host"], target=conf.get("target", "laser1")) except OSError: logger.warning( "could not connect to laser '{}', retrying in 60s" .format(laser)) if conf["locked"]: self.control_interface.unlock(laser, conf["lock_owner"]) await asyncio.sleep(60) continue self.wake_locks[laser].set() conf["lock_ready"] = True while self.running: if not conf["locked"]: await self.wake_locks[laser].wait() self.wake_locks[laser].clear() continue poll_time = conf["lock_poll_time"] locked_at = conf["locked_at"] timeout = conf["lock_timeout"] set_point = conf["lock_set_point"] gain = conf["lock_gain"] * poll_time capture_range = conf["lock_capture_range"] await asyncio.wait({self.wake_locks[laser].wait()}, timeout=poll_time) self.wake_locks[laser].clear() if timeout is not None and time.time() > (locked_at + timeout): logger.info("'{}'' lock timed out".format(laser)) self.control_interface.unlock(laser, conf["lock_owner"]) await asyncio.sleep(0) continue status, delta, _ = await self.control_interface.get_freq( laser, age=0, priority=5, get_osa_trace=False, blocking=True, mute=False, offset_mode=True) if status != WLMMeasurementStatus.OKAY: continue f_error = delta - set_point V_error = f_error * gain if abs(f_error) > capture_range: logger.warning("'{}'' outside capture range".format(laser)) self.control_interface.unlock(laser, conf["lock_owner"]) await asyncio.sleep(0) continue # don't drive the PZT too far in a single step V_error = min(V_error, 0.25) V_error = max(V_error, -0.25) try: v_pzt = iface.get_pzt_voltage() v_pzt -= V_error if v_pzt > 100 or v_pzt < 25: logger.warning("'{}'' lock railed".format(laser)) self.control_interface.unlock(laser, conf["lock_owner"]) await asyncio.sleep(0) continue iface.set_pzt_voltage(v_pzt) except OSError: logger.warning("Connection to laser '{}' lost" .format(laser)) self.control_interface.unlock(laser, conf["lock_owner"]) await asyncio.sleep(0) break try: iface.close() except Exception: pass finally: conf["lock_ready"] = False async def measurement_task(self): """ Process queued measurements """ active_laser = "" while True: if self.queue == []: self.measurements_queued.clear() await self.measurements_queued.wait() # process in order of priority, followed by submission time priorities = [meas["priority"] for meas in self.queue] meas = self.queue[priorities.index(max(priorities))] laser = meas["laser"] laser_conf = self.laser_db.raw_view[laser] if laser != active_laser: self.switch.set_active_channel(laser_conf["channel"]) # Switching is slow so we might as well take an OSA trace! meas["get_osa_trace"] = True active_laser = meas["laser"] # We only need to change the range after switching channels try: range_ = laser_conf.get("wavelength_range") self.wlm.set_wavelength_range(range_) except WLMException: pass await asyncio.sleep(self.config["switch"]["dead_time"]) exposure = laser_conf["exposure"] for ccd, exp in enumerate(exposure): self.wlm.set_exposure(exposure[ccd], ccd) if laser_conf.get("osa", "wlm") == "wlm": freq_osa_measurement = self.loop.run_in_executor( self.executor, self.take_freq_osa_measurement, laser, laser_conf["f_ref"], meas["get_osa_trace"]) wlm_data, osa = await freq_osa_measurement else: freq_measurement = self.loop.run_in_executor( self.executor, self.take_freq_measurement, laser, laser_conf["f_ref"]) osa_measurement = self.loop.run_in_executor( self.executor, self.take_osa_measurement, laser, laser_conf.get("osa"), meas["get_osa_trace"]) wlm_data, osa = (await asyncio.gather(freq_measurement, osa_measurement))[:] freq, peaks = wlm_data self.freq_db[laser] = freq if meas["get_osa_trace"]: self.osa_db[laser] = osa # fast mode timeout if laser_conf["fast_mode"]: t_en = laser_conf["fast_mode_set_at"] if time.time() > (t_en + self.args.fast_mode_timeout): self.laser_db[laser]["fast_mode"] = False self.save_config_file() logger.info("{} fast mode timeout".format(laser)) # auto-exposure if laser_conf["auto_exposure"]: new_exp = laser_conf["exposure"] for ccd, peak in enumerate(peaks): # don't try to find a suitable exposure for lasers that # aren't on! if peak < 0.05: break if not (0.4 < peak < 0.6): exp = laser_conf["exposure"][ccd] new_exp[ccd] = exp + 1 if peak < 0.4 else exp - 1 new_exp[ccd] = min(new_exp[ccd], self.exp_max[ccd]) new_exp[ccd] = max(new_exp[ccd], self.exp_min[ccd]) if new_exp != exp: self.laser_db[laser]["exposure"] = new_exp self.save_config_file() # check which other measurements wanted this data for task in self.queue: if task["laser"] == laser \ and (meas["get_osa_trace"] or not task["get_osa_trace"]): task["done"].set() self.queue.remove(task) logger.info("task {} complete".format(task["id"])) def take_freq_measurement(self, laser, f0): """ Preform a single frequency measurement """ logger.info("Taking new frequency measurement for {}".format(laser)) status, freq = self.wlm.get_frequency() freq = { "freq": freq, "status": int(status), "timestamp": time.time() } # make simulation data more interesting! if self.args.simulation: freq["freq"] = f0 + np.random.normal(loc=0, scale=10e6) peaks = [self.wlm.get_fringe_peak(ccd) for ccd in range(self.num_ccds)] return freq, peaks def take_osa_measurement(self, laser, osa, get_osa_trace): """ Capture an osa trace """ if not get_osa_trace: return { "trace": None, "timestamp": time.time() } osa = {"trace": self.osas.get_trace(osa).tolist(), "timestamp": time.time() } return osa def take_freq_osa_measurement(self, laser, f0, get_osa_trace): """ Get frequency and spectral data from the wlm """ logger.info("Taking new frequency + spectral measurement for {}" .format(laser)) status, freq = self.wlm.get_frequency() freq = { "freq": freq, "status": int(status), "timestamp": time.time() } # make simulation data more interesting! if self.args.simulation: freq["freq"] = f0 + np.random.normal(loc=0, scale=10e6) peaks = [self.wlm.get_fringe_peak(ccd) for ccd in range(self.num_ccds)] if not get_osa_trace: osa = { "trace": None, "timestamp": time.time() } else: osa = {"trace": self.wlm.get_pattern().tolist(), "timestamp": time.time() } return (freq, peaks), osa def save_config_file(self): try: self.config["lasers"] = self.laser_db.raw_view config_path, _ = get_config_path(self.args, "_server") pyon.store_file(config_path, self.config) except Exception: log.warning("error when trying to save config data")
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))
async def do_test(self): server = Server({"target": Target()}) await server.start("::1", 7777) await self.check_value() await server.stop()
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()
def main(): args = get_argparser().parse_args() log_forwarder = init_log(args) if os.name == "nt": loop = asyncio.ProactorEventLoop() asyncio.set_event_loop(loop) else: loop = asyncio.get_event_loop() atexit.register(loop.close) bind = common_args.bind_address_from_args(args) server_broadcast = Broadcaster() loop.run_until_complete(server_broadcast.start( bind, args.port_broadcast)) atexit_register_coroutine(server_broadcast.stop) log_forwarder.callback = (lambda msg: server_broadcast.broadcast("log", msg)) def ccb_issue(service, *args, **kwargs): msg = { "service": service, "args": args, "kwargs": kwargs } server_broadcast.broadcast("ccb", msg) device_db = DeviceDB(args.device_db) dataset_db = DatasetDB(args.dataset_db) dataset_db.start() atexit_register_coroutine(dataset_db.stop) worker_handlers = dict() if args.git: repo_backend = GitBackend(args.repository) else: repo_backend = FilesystemBackend(args.repository) experiment_db = ExperimentDB( repo_backend, worker_handlers, args.experiment_subdir) atexit.register(experiment_db.close) scheduler = Scheduler(RIDCounter(), worker_handlers, experiment_db) scheduler.start() atexit_register_coroutine(scheduler.stop) config = MasterConfig(args.name) worker_handlers.update({ "get_device_db": device_db.get_device_db, "get_device": device_db.get, "get_dataset": dataset_db.get, "update_dataset": dataset_db.update, "scheduler_submit": scheduler.submit, "scheduler_delete": scheduler.delete, "scheduler_request_termination": scheduler.request_termination, "scheduler_get_status": scheduler.get_status, "scheduler_check_pause": scheduler.check_pause, "ccb_issue": ccb_issue, }) experiment_db.scan_repository_async() server_control = RPCServer({ "master_config": config, "master_device_db": device_db, "master_dataset_db": dataset_db, "master_schedule": scheduler, "master_experiment_db": experiment_db }, allow_parallel=True) loop.run_until_complete(server_control.start( bind, args.port_control)) atexit_register_coroutine(server_control.stop) server_notify = Publisher({ "schedule": scheduler.notifier, "devices": device_db.data, "datasets": dataset_db.data, "explist": experiment_db.explist, "explist_status": experiment_db.status }) loop.run_until_complete(server_notify.start( bind, args.port_notify)) atexit_register_coroutine(server_notify.stop) server_logging = LoggingServer() loop.run_until_complete(server_logging.start( bind, args.port_logging)) atexit_register_coroutine(server_logging.stop) print("ARTIQ master is now ready.") loop.run_forever()
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)
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_)
def __init__(self): self.args = args = get_argparser().parse_args() init_logger_from_args(args) self.config = load_config(args, "_server") self.lasers = self.config["lasers"].keys() for laser in self.lasers: self.config["lasers"][laser]["lock_ready"] = False # connect to hardware self.wlm = WLM(args.simulation) if self.config.get("osas", "wlm") != "wlm": self.osas = NiOSA(self.config["osas"], args.simulation) self.exp_min = self.wlm.get_exposure_min() self.exp_max = self.wlm.get_exposure_max() self.num_ccds = self.wlm.get_num_ccds() if self.config["switch"]["type"] == "internal": self.switch = self.wlm.get_switch() elif self.config["switch"]["type"] == "leoni": self.switch = LeoniSwitch( self.config["switch"]["ip"], args.simulation) else: raise ValueError("Unrecognised switch type: {}".format( self.config["switch"]["type"])) # measurement queue, processed by self.measurement_task self.measurement_ids = task_id_generator() self.measurements_queued = asyncio.Event() self.queue = [] self.wake_locks = {laser: asyncio.Event() for laser in self.lasers} # schedule initial frequency/osa readings all lasers self.measurements_queued.set() for laser in self.lasers: self.queue.append({ "laser": laser, "priority": 0, "expiry": time.time(), "id": next(self.measurement_ids), "get_osa_trace": True, "done": asyncio.Event() }) # "notify" interface self.laser_db = Notifier(self.config["lasers"]) self.freq_db = Notifier({laser: { "freq": None, "status": WLMMeasurementStatus.ERROR, "timestamp": 0 } for laser in self.lasers}) self.osa_db = Notifier({laser: { "trace": None, "timestamp": 0 } for laser in self.lasers}) self.server_notify = Publisher({ "laser_db": self.laser_db, # laser settings "freq_db": self.freq_db, # most recent frequency measurements "osa_db": self.osa_db # most recent osa traces }) # "control" interface self.control_interface = ControlInterface(self) self.server_control = RPCServer({"control": self.control_interface}, allow_parallel=True) self.running = False