forked from M-Labs/artiq
Compare commits
10 Commits
3ecd115252
...
12db9b106d
Author | SHA1 | Date |
---|---|---|
Simon Renblad | 12db9b106d | |
Simon Renblad | c6194eb430 | |
Norman Krackow | baa58343ac | |
Sébastien Bourdeauducq | 1bcbee988d | |
Sébastien Bourdeauducq | ab206ac154 | |
Simon Renblad | 4a2352c2df | |
Simon Renblad | f9a447e8e0 | |
Simon Renblad | c4892cf285 | |
Simon Renblad | c1e6ae2193 | |
Simon Renblad | 4f302ee675 |
|
@ -29,7 +29,7 @@ Website: https://m-labs.hk/artiq
|
||||||
License
|
License
|
||||||
=======
|
=======
|
||||||
|
|
||||||
Copyright (C) 2014-2023 M-Labs Limited.
|
Copyright (C) 2014-2024 M-Labs Limited.
|
||||||
|
|
||||||
ARTIQ is free software: you can redistribute it and/or modify
|
ARTIQ is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU Lesser General Public License as published by
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
|
|
@ -369,6 +369,8 @@ class ExperimentsArea(QtWidgets.QMdiArea):
|
||||||
def initialize_submission_arguments(self, arginfo):
|
def initialize_submission_arguments(self, arginfo):
|
||||||
arguments = OrderedDict()
|
arguments = OrderedDict()
|
||||||
for name, (procdesc, group, tooltip) in arginfo.items():
|
for name, (procdesc, group, tooltip) in arginfo.items():
|
||||||
|
if procdesc["ty"] == "EnumerationValue" and procdesc["quickstyle"]:
|
||||||
|
procdesc["quickstyle"] = False
|
||||||
state = procdesc_to_entry(procdesc).default_state(procdesc)
|
state = procdesc_to_entry(procdesc).default_state(procdesc)
|
||||||
arguments[name] = {
|
arguments[name] = {
|
||||||
"desc": procdesc,
|
"desc": procdesc,
|
||||||
|
|
|
@ -999,7 +999,7 @@ class AD9910:
|
||||||
"""
|
"""
|
||||||
if not self.cpld.sync_div:
|
if not self.cpld.sync_div:
|
||||||
raise ValueError("parent cpld does not drive SYNC")
|
raise ValueError("parent cpld does not drive SYNC")
|
||||||
search_span = 31
|
search_span = 13
|
||||||
# FIXME https://github.com/sinara-hw/Urukul/issues/16
|
# FIXME https://github.com/sinara-hw/Urukul/issues/16
|
||||||
# should both be 2-4 once kasli sync_in jitter is identified
|
# should both be 2-4 once kasli sync_in jitter is identified
|
||||||
min_window = 0
|
min_window = 0
|
||||||
|
|
|
@ -94,7 +94,7 @@ class _OpenFileDialog(QtWidgets.QDialog):
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
self.explorer.current_directory = \
|
self.explorer.current_directory = \
|
||||||
self.explorer.current_directory[:idx+1]
|
self.explorer.current_directory[:idx + 1]
|
||||||
if self.explorer.current_directory == "/":
|
if self.explorer.current_directory == "/":
|
||||||
self.explorer.current_directory = ""
|
self.explorer.current_directory = ""
|
||||||
asyncio.ensure_future(self.refresh_view())
|
asyncio.ensure_future(self.refresh_view())
|
||||||
|
@ -103,6 +103,7 @@ class _OpenFileDialog(QtWidgets.QDialog):
|
||||||
asyncio.ensure_future(self.refresh_view())
|
asyncio.ensure_future(self.refresh_view())
|
||||||
else:
|
else:
|
||||||
file = self.explorer.current_directory + selected
|
file = self.explorer.current_directory + selected
|
||||||
|
|
||||||
async def open_task():
|
async def open_task():
|
||||||
try:
|
try:
|
||||||
await self.exp_manager.open_file(file)
|
await self.exp_manager.open_file(file)
|
||||||
|
@ -232,7 +233,7 @@ class ExplorerDock(QtWidgets.QDockWidget):
|
||||||
|
|
||||||
set_shortcut_menu = QtWidgets.QMenu()
|
set_shortcut_menu = QtWidgets.QMenu()
|
||||||
for i in range(12):
|
for i in range(12):
|
||||||
action = QtWidgets.QAction("F" + str(i+1), self.el)
|
action = QtWidgets.QAction("F" + str(i + 1), self.el)
|
||||||
action.triggered.connect(partial(self.set_shortcut, i))
|
action.triggered.connect(partial(self.set_shortcut, i))
|
||||||
set_shortcut_menu.addAction(action)
|
set_shortcut_menu.addAction(action)
|
||||||
|
|
||||||
|
@ -246,12 +247,14 @@ class ExplorerDock(QtWidgets.QDockWidget):
|
||||||
|
|
||||||
scan_repository_action = QtWidgets.QAction("Scan repository HEAD",
|
scan_repository_action = QtWidgets.QAction("Scan repository HEAD",
|
||||||
self.el)
|
self.el)
|
||||||
|
|
||||||
def scan_repository():
|
def scan_repository():
|
||||||
asyncio.ensure_future(experiment_db_ctl.scan_repository_async())
|
asyncio.ensure_future(experiment_db_ctl.scan_repository_async())
|
||||||
scan_repository_action.triggered.connect(scan_repository)
|
scan_repository_action.triggered.connect(scan_repository)
|
||||||
self.el.addAction(scan_repository_action)
|
self.el.addAction(scan_repository_action)
|
||||||
|
|
||||||
scan_ddb_action = QtWidgets.QAction("Scan device database", self.el)
|
scan_ddb_action = QtWidgets.QAction("Scan device database", self.el)
|
||||||
|
|
||||||
def scan_ddb():
|
def scan_ddb():
|
||||||
asyncio.ensure_future(device_db_ctl.scan())
|
asyncio.ensure_future(device_db_ctl.scan())
|
||||||
scan_ddb_action.triggered.connect(scan_ddb)
|
scan_ddb_action.triggered.connect(scan_ddb)
|
||||||
|
@ -292,7 +295,7 @@ class ExplorerDock(QtWidgets.QDockWidget):
|
||||||
if expname is not None:
|
if expname is not None:
|
||||||
expurl = "repo:" + expname
|
expurl = "repo:" + expname
|
||||||
self.d_shortcuts.set_shortcut(nr, expurl)
|
self.d_shortcuts.set_shortcut(nr, expurl)
|
||||||
logger.info("Set shortcut F%d to '%s'", nr+1, expurl)
|
logger.info("Set shortcut F%d to '%s'", nr + 1, expurl)
|
||||||
|
|
||||||
def update_scanning(self, scanning):
|
def update_scanning(self, scanning):
|
||||||
if scanning:
|
if scanning:
|
||||||
|
|
|
@ -363,61 +363,72 @@ class _DACWidget(_SimpleDisplayWidget):
|
||||||
return (self.spi_channel, self.channel)
|
return (self.spi_channel, self.channel)
|
||||||
|
|
||||||
|
|
||||||
_WidgetDesc = namedtuple("_WidgetDesc", "uid comment cls arguments")
|
_ChannelDesc = namedtuple("_ChannelDesc", "name widget_type clss kwargs")
|
||||||
|
|
||||||
|
|
||||||
|
def _setup_ttl(k, v, description):
|
||||||
|
if "ttl_urukul" in k:
|
||||||
|
return
|
||||||
|
channel = v["arguments"]["channel"]
|
||||||
|
channel_desc = _ChannelDesc(k, _TTLWidget, v["class"], {})
|
||||||
|
description[(channel, None)] = channel_desc
|
||||||
|
|
||||||
|
|
||||||
|
def _setup_ad9914(k, v, description):
|
||||||
|
bus_channel = v["arguments"]["bus_channel"]
|
||||||
|
channel = v["arguments"]["channel"]
|
||||||
|
dds_sysclk = v["arguments"]["sysclk"]
|
||||||
|
channel_desc = _ChannelDesc(k, _DDSWidget, v["class"],
|
||||||
|
{"dds_sysclk": dds_sysclk})
|
||||||
|
description[(bus_channel, channel)] = channel_desc
|
||||||
|
|
||||||
|
|
||||||
|
def _setup_urukul(k, v, description, ddb):
|
||||||
|
channel = v["arguments"]["chip_select"] - 4
|
||||||
|
if channel < 0:
|
||||||
|
return
|
||||||
|
dds_cpld = v["arguments"]["cpld_device"]
|
||||||
|
spi_dev = ddb[dds_cpld]["arguments"]["spi_device"]
|
||||||
|
bus_channel = ddb[spi_dev]["arguments"]["channel"]
|
||||||
|
pll = v["arguments"]["pll_n"]
|
||||||
|
refclk = ddb[dds_cpld]["arguments"]["refclk"]
|
||||||
|
clk_div = v["arguments"].get("clk_div", 0)
|
||||||
|
channel_desc = _ChannelDesc(k, _DDSWidget, v["class"],
|
||||||
|
{"refclk": refclk, "dds_cpld": dds_cpld,
|
||||||
|
"pll": pll, "clk_div": clk_div})
|
||||||
|
description[(bus_channel, channel)] = channel_desc
|
||||||
|
|
||||||
|
|
||||||
|
def _setup_dac(k, v, description, ddb):
|
||||||
|
spi_device = v["arguments"]["spi_device"]
|
||||||
|
spi_device = ddb[spi_device]
|
||||||
|
while isinstance(spi_device, str):
|
||||||
|
spi_device = ddb[spi_device]
|
||||||
|
spi_channel = spi_device["arguments"]["channel"]
|
||||||
|
for channel in range(32):
|
||||||
|
channel_desc = _ChannelDesc(k, _DACWidget, v["class"], {})
|
||||||
|
description[(spi_channel, channel)] = channel_desc
|
||||||
|
|
||||||
|
|
||||||
def setup_from_ddb(ddb):
|
def setup_from_ddb(ddb):
|
||||||
mi_addr = None
|
mi_addr = None
|
||||||
mi_port = None
|
mi_port = None
|
||||||
dds_sysclk = None
|
description = dict() # (uid, channel) -> _ChannelDesc
|
||||||
description = set()
|
|
||||||
|
|
||||||
for k, v in ddb.items():
|
for k, v in ddb.items():
|
||||||
try:
|
try:
|
||||||
if isinstance(v, dict):
|
if isinstance(v, dict):
|
||||||
comment = v.get("comment")
|
|
||||||
if v["type"] == "local":
|
if v["type"] == "local":
|
||||||
if v["module"] == "artiq.coredevice.ttl":
|
if v["module"] == "artiq.coredevice.ttl":
|
||||||
if "ttl_urukul" in k:
|
_setup_ttl(k, v, description)
|
||||||
continue
|
|
||||||
channel = v["arguments"]["channel"]
|
|
||||||
force_out = v["class"] == "TTLOut"
|
|
||||||
widget = _WidgetDesc(k, comment, _TTLWidget, (channel, force_out, k))
|
|
||||||
description.add(widget)
|
|
||||||
elif (v["module"] == "artiq.coredevice.ad9914" and v["class"] == "AD9914"):
|
elif (v["module"] == "artiq.coredevice.ad9914" and v["class"] == "AD9914"):
|
||||||
bus_channel = v["arguments"]["bus_channel"]
|
_setup_ad9914(k, v, description)
|
||||||
channel = v["arguments"]["channel"]
|
|
||||||
dds_sysclk = v["arguments"]["sysclk"]
|
|
||||||
model = _DDSModel(v["class"], dds_sysclk)
|
|
||||||
widget = _WidgetDesc(k, comment, _DDSWidget,
|
|
||||||
(k, bus_channel, channel, model))
|
|
||||||
description.add(widget)
|
|
||||||
elif (v["module"] == "artiq.coredevice.ad9910" and v["class"] == "AD9910") or \
|
elif (v["module"] == "artiq.coredevice.ad9910" and v["class"] == "AD9910") or \
|
||||||
(v["module"] == "artiq.coredevice.ad9912" and v["class"] == "AD9912"):
|
(v["module"] == "artiq.coredevice.ad9912" and v["class"] == "AD9912"):
|
||||||
channel = v["arguments"]["chip_select"] - 4
|
_setup_urukul(k, v, description, ddb)
|
||||||
if channel < 0:
|
|
||||||
continue
|
|
||||||
dds_cpld = v["arguments"]["cpld_device"]
|
|
||||||
spi_dev = ddb[dds_cpld]["arguments"]["spi_device"]
|
|
||||||
bus_channel = ddb[spi_dev]["arguments"]["channel"]
|
|
||||||
pll = v["arguments"]["pll_n"]
|
|
||||||
refclk = ddb[dds_cpld]["arguments"]["refclk"]
|
|
||||||
clk_div = v["arguments"].get("clk_div", 0)
|
|
||||||
model = _DDSModel(v["class"], refclk, dds_cpld, pll, clk_div)
|
|
||||||
widget = _WidgetDesc(k, comment, _DDSWidget,
|
|
||||||
(k, bus_channel, channel, model))
|
|
||||||
description.add(widget)
|
|
||||||
elif (v["module"] == "artiq.coredevice.ad53xx" and v["class"] == "AD53xx") or \
|
elif (v["module"] == "artiq.coredevice.ad53xx" and v["class"] == "AD53xx") or \
|
||||||
(v["module"] == "artiq.coredevice.zotino" and v["class"] == "Zotino"):
|
(v["module"] == "artiq.coredevice.zotino" and v["class"] == "Zotino"):
|
||||||
spi_device = v["arguments"]["spi_device"]
|
_setup_dac(k, v, description, ddb)
|
||||||
spi_device = ddb[spi_device]
|
|
||||||
while isinstance(spi_device, str):
|
|
||||||
spi_device = ddb[spi_device]
|
|
||||||
spi_channel = spi_device["arguments"]["channel"]
|
|
||||||
for channel in range(32):
|
|
||||||
widget = _WidgetDesc((k, channel), comment, _DACWidget,
|
|
||||||
(spi_channel, channel, k))
|
|
||||||
description.add(widget)
|
|
||||||
elif v["type"] == "controller" and k == "core_moninj":
|
elif v["type"] == "controller" and k == "core_moninj":
|
||||||
mi_addr = v["host"]
|
mi_addr = v["host"]
|
||||||
mi_port = v.get("port_proxy", 1383)
|
mi_port = v.get("port_proxy", 1383)
|
||||||
|
@ -437,16 +448,14 @@ class _DeviceManager:
|
||||||
self.schedule_ctl = schedule_ctl
|
self.schedule_ctl = schedule_ctl
|
||||||
|
|
||||||
self.ddb = dict()
|
self.ddb = dict()
|
||||||
self.description = set()
|
|
||||||
self.widgets_by_uid = dict()
|
# only modified by notify_ddb
|
||||||
|
self.description = dict()
|
||||||
|
|
||||||
|
self.displayed_channels = dict()
|
||||||
|
|
||||||
self.dds_sysclk = 0
|
self.dds_sysclk = 0
|
||||||
self.ttl_cb = lambda: None
|
self.refresh_display_cb = lambda: None
|
||||||
self.ttl_widgets = dict()
|
|
||||||
self.dds_cb = lambda: None
|
|
||||||
self.dds_widgets = dict()
|
|
||||||
self.dac_cb = lambda: None
|
|
||||||
self.dac_widgets = dict()
|
|
||||||
|
|
||||||
def init_ddb(self, ddb):
|
def init_ddb(self, ddb):
|
||||||
self.ddb = ddb
|
self.ddb = ddb
|
||||||
|
@ -454,56 +463,13 @@ class _DeviceManager:
|
||||||
def notify_ddb(self, mod):
|
def notify_ddb(self, mod):
|
||||||
mi_addr, mi_port, description = setup_from_ddb(self.ddb)
|
mi_addr, mi_port, description = setup_from_ddb(self.ddb)
|
||||||
|
|
||||||
if (mi_addr, mi_port) != (self.mi_addr, self.mi_port):
|
if (mi_addr, mi_port, description) != (self.mi_addr, self.mi_port, self.description):
|
||||||
self.mi_addr = mi_addr
|
self.mi_addr = mi_addr
|
||||||
self.mi_port = mi_port
|
self.mi_port = mi_port
|
||||||
|
self.description = description
|
||||||
|
self.refresh_display_cb()
|
||||||
self.reconnect_mi.set()
|
self.reconnect_mi.set()
|
||||||
|
|
||||||
for to_remove in self.description - description:
|
|
||||||
widget = self.widgets_by_uid[to_remove.uid]
|
|
||||||
del self.widgets_by_uid[to_remove.uid]
|
|
||||||
|
|
||||||
if isinstance(widget, _TTLWidget):
|
|
||||||
self.setup_ttl_monitoring(False, widget.channel)
|
|
||||||
widget.deleteLater()
|
|
||||||
del self.ttl_widgets[widget.channel]
|
|
||||||
self.ttl_cb()
|
|
||||||
elif isinstance(widget, _DDSWidget):
|
|
||||||
self.setup_dds_monitoring(False, widget.bus_channel, widget.channel)
|
|
||||||
widget.deleteLater()
|
|
||||||
del self.dds_widgets[(widget.bus_channel, widget.channel)]
|
|
||||||
self.dds_cb()
|
|
||||||
elif isinstance(widget, _DACWidget):
|
|
||||||
self.setup_dac_monitoring(False, widget.spi_channel, widget.channel)
|
|
||||||
widget.deleteLater()
|
|
||||||
del self.dac_widgets[(widget.spi_channel, widget.channel)]
|
|
||||||
self.dac_cb()
|
|
||||||
else:
|
|
||||||
raise ValueError
|
|
||||||
|
|
||||||
for to_add in description - self.description:
|
|
||||||
widget = to_add.cls(self, *to_add.arguments)
|
|
||||||
if to_add.comment is not None:
|
|
||||||
widget.setToolTip(to_add.comment)
|
|
||||||
self.widgets_by_uid[to_add.uid] = widget
|
|
||||||
|
|
||||||
if isinstance(widget, _TTLWidget):
|
|
||||||
self.ttl_widgets[widget.channel] = widget
|
|
||||||
self.ttl_cb()
|
|
||||||
self.setup_ttl_monitoring(True, widget.channel)
|
|
||||||
elif isinstance(widget, _DDSWidget):
|
|
||||||
self.dds_widgets[(widget.bus_channel, widget.channel)] = widget
|
|
||||||
self.dds_cb()
|
|
||||||
self.setup_dds_monitoring(True, widget.bus_channel, widget.channel)
|
|
||||||
elif isinstance(widget, _DACWidget):
|
|
||||||
self.dac_widgets[(widget.spi_channel, widget.channel)] = widget
|
|
||||||
self.dac_cb()
|
|
||||||
self.setup_dac_monitoring(True, widget.spi_channel, widget.channel)
|
|
||||||
else:
|
|
||||||
raise ValueError
|
|
||||||
|
|
||||||
self.description = description
|
|
||||||
|
|
||||||
def ttl_set_mode(self, channel, mode):
|
def ttl_set_mode(self, channel, mode):
|
||||||
if self.mi_connection is not None:
|
if self.mi_connection is not None:
|
||||||
widget = self.ttl_widgets[channel]
|
widget = self.ttl_widgets[channel]
|
||||||
|
@ -655,6 +621,15 @@ class _DeviceManager:
|
||||||
"ToggleDDS",
|
"ToggleDDS",
|
||||||
"Toggle DDS {} {}".format(dds_channel, "on" if sw else "off"))
|
"Toggle DDS {} {}".format(dds_channel, "on" if sw else "off"))
|
||||||
|
|
||||||
|
def setup_monitoring(self, uid, enable):
|
||||||
|
widget_type = self.description[uid].widget_type
|
||||||
|
if widget_type == "TTL":
|
||||||
|
self.setup_ttl_monitoring(enable, uid[0])
|
||||||
|
elif widget_type == "DDS":
|
||||||
|
self.setup_dds_monitoring(enable, *uid)
|
||||||
|
elif widget_type == "DAC":
|
||||||
|
self.setup_dac_monitoring(enable, *uid)
|
||||||
|
|
||||||
def setup_ttl_monitoring(self, enable, channel):
|
def setup_ttl_monitoring(self, enable, channel):
|
||||||
if self.mi_connection is not None:
|
if self.mi_connection is not None:
|
||||||
self.mi_connection.monitor_probe(enable, channel, TTLProbe.level.value)
|
self.mi_connection.monitor_probe(enable, channel, TTLProbe.level.value)
|
||||||
|
@ -673,30 +648,15 @@ class _DeviceManager:
|
||||||
self.mi_connection.monitor_probe(enable, spi_channel, channel)
|
self.mi_connection.monitor_probe(enable, spi_channel, channel)
|
||||||
|
|
||||||
def monitor_cb(self, channel, probe, value):
|
def monitor_cb(self, channel, probe, value):
|
||||||
if channel in self.ttl_widgets:
|
if (channel, None) in self.displayed_channels:
|
||||||
widget = self.ttl_widgets[channel]
|
self.displayed_channels[(channel, None)].monitor_cb(probe, value)
|
||||||
if probe == TTLProbe.level.value:
|
elif (channel, probe) in self.displayed_channels:
|
||||||
widget.cur_level = bool(value)
|
self.displayed_channels[(channel, probe)].monitor_cb(probe, value)
|
||||||
elif probe == TTLProbe.oe.value:
|
|
||||||
widget.cur_oe = bool(value)
|
|
||||||
widget.refresh_display()
|
|
||||||
elif (channel, probe) in self.dds_widgets:
|
|
||||||
widget = self.dds_widgets[(channel, probe)]
|
|
||||||
widget.dds_model.monitor_update(probe, value)
|
|
||||||
widget.refresh_display()
|
|
||||||
elif (channel, probe) in self.dac_widgets:
|
|
||||||
widget = self.dac_widgets[(channel, probe)]
|
|
||||||
widget.cur_value = value
|
|
||||||
widget.refresh_display()
|
|
||||||
|
|
||||||
def injection_status_cb(self, channel, override, value):
|
def injection_status_cb(self, channel, override, value):
|
||||||
if channel in self.ttl_widgets:
|
if (channel, None) in self.displayed_channels and \
|
||||||
widget = self.ttl_widgets[channel]
|
self.description[(channel, None)].widget_type == "TTL":
|
||||||
if override == TTLOverride.en.value:
|
self.displayed_channels[(channel, None)].injection_status_cb(override, value)
|
||||||
widget.cur_override = bool(value)
|
|
||||||
if override == TTLOverride.level.value:
|
|
||||||
widget.cur_override_level = bool(value)
|
|
||||||
widget.refresh_display()
|
|
||||||
|
|
||||||
def disconnect_cb(self):
|
def disconnect_cb(self):
|
||||||
logger.error("lost connection to moninj")
|
logger.error("lost connection to moninj")
|
||||||
|
@ -722,12 +682,8 @@ class _DeviceManager:
|
||||||
logger.info("ARTIQ dashboard connected to moninj (%s)",
|
logger.info("ARTIQ dashboard connected to moninj (%s)",
|
||||||
self.mi_addr)
|
self.mi_addr)
|
||||||
self.mi_connection = new_mi_connection
|
self.mi_connection = new_mi_connection
|
||||||
for ttl_channel in self.ttl_widgets.keys():
|
for key in self.displayed_channels:
|
||||||
self.setup_ttl_monitoring(True, ttl_channel)
|
self.setup_monitoring(key, True)
|
||||||
for bus_channel, channel in self.dds_widgets.keys():
|
|
||||||
self.setup_dds_monitoring(True, bus_channel, channel)
|
|
||||||
for spi_channel, channel in self.dac_widgets.keys():
|
|
||||||
self.setup_dac_monitoring(True, spi_channel, channel)
|
|
||||||
|
|
||||||
async def close(self):
|
async def close(self):
|
||||||
self.mi_connector_task.cancel()
|
self.mi_connector_task.cancel()
|
||||||
|
@ -739,38 +695,28 @@ class _DeviceManager:
|
||||||
await self.mi_connection.close()
|
await self.mi_connection.close()
|
||||||
|
|
||||||
|
|
||||||
class _MonInjDock(QtWidgets.QDockWidget):
|
class MonInjDock(QtWidgets.QDockWidget):
|
||||||
def __init__(self, name):
|
def __init__(self, schedule_ctl):
|
||||||
QtWidgets.QDockWidget.__init__(self, name)
|
QtWidgets.QDockWidget.__init__(self, "MonInj")
|
||||||
self.setObjectName(name)
|
self.setObjectName("MonInj")
|
||||||
self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable |
|
self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable |
|
||||||
QtWidgets.QDockWidget.DockWidgetFloatable)
|
QtWidgets.QDockWidget.DockWidgetFloatable)
|
||||||
|
|
||||||
def layout_widgets(self, widgets):
|
|
||||||
scroll_area = QtWidgets.QScrollArea()
|
scroll_area = QtWidgets.QScrollArea()
|
||||||
|
scroll_area.setWidgetResizable(True)
|
||||||
self.setWidget(scroll_area)
|
self.setWidget(scroll_area)
|
||||||
|
|
||||||
grid = FlowLayout()
|
self.grid = FlowLayout()
|
||||||
grid_widget = QtWidgets.QWidget()
|
grid_widget = QtWidgets.QWidget()
|
||||||
grid_widget.setLayout(grid)
|
grid_widget.setLayout(self.grid)
|
||||||
|
|
||||||
for widget in sorted(widgets, key=lambda w: w.sort_key()):
|
|
||||||
grid.addWidget(widget)
|
|
||||||
|
|
||||||
scroll_area.setWidgetResizable(True)
|
|
||||||
scroll_area.setWidget(grid_widget)
|
scroll_area.setWidget(grid_widget)
|
||||||
|
|
||||||
|
|
||||||
class MonInj:
|
|
||||||
def __init__(self, schedule_ctl):
|
|
||||||
self.ttl_dock = _MonInjDock("TTL")
|
|
||||||
self.dds_dock = _MonInjDock("DDS")
|
|
||||||
self.dac_dock = _MonInjDock("DAC")
|
|
||||||
|
|
||||||
self.dm = _DeviceManager(schedule_ctl)
|
self.dm = _DeviceManager(schedule_ctl)
|
||||||
self.dm.ttl_cb = lambda: self.ttl_dock.layout_widgets(self.dm.ttl_widgets.values())
|
self.dm.refresh_display_cb = self.refresh_display_cb
|
||||||
self.dm.dds_cb = lambda: self.dds_dock.layout_widgets(self.dm.dds_widgets.values())
|
|
||||||
self.dm.dac_cb = lambda: self.dac_dock.layout_widgets(self.dm.dac_widgets.values())
|
def layout_widgets(self, widgets):
|
||||||
|
for widget in sorted(widgets, key=lambda w: w.sort_key()):
|
||||||
|
self.grid.addWidget(widget)
|
||||||
|
|
||||||
async def stop(self):
|
async def stop(self):
|
||||||
if self.dm is not None:
|
if self.dm is not None:
|
||||||
|
|
|
@ -15,9 +15,8 @@ logger = logging.getLogger(__name__)
|
||||||
class Model(DictSyncModel):
|
class Model(DictSyncModel):
|
||||||
def __init__(self, init):
|
def __init__(self, init):
|
||||||
DictSyncModel.__init__(self,
|
DictSyncModel.__init__(self,
|
||||||
["RID", "Pipeline", "Status", "Prio", "Due date",
|
["RID", "Pipeline", "Status", "Prio", "Due date",
|
||||||
"Revision", "File", "Class name"],
|
"Revision", "File", "Class name"], init)
|
||||||
init)
|
|
||||||
|
|
||||||
def sort_key(self, k, v):
|
def sort_key(self, k, v):
|
||||||
# order by priority, and then by due date and RID
|
# order by priority, and then by due date and RID
|
||||||
|
@ -96,14 +95,14 @@ class ScheduleDock(QtWidgets.QDockWidget):
|
||||||
|
|
||||||
cw = QtGui.QFontMetrics(self.font()).averageCharWidth()
|
cw = QtGui.QFontMetrics(self.font()).averageCharWidth()
|
||||||
h = self.table.horizontalHeader()
|
h = self.table.horizontalHeader()
|
||||||
h.resizeSection(0, 7*cw)
|
h.resizeSection(0, 7 * cw)
|
||||||
h.resizeSection(1, 12*cw)
|
h.resizeSection(1, 12 * cw)
|
||||||
h.resizeSection(2, 16*cw)
|
h.resizeSection(2, 16 * cw)
|
||||||
h.resizeSection(3, 6*cw)
|
h.resizeSection(3, 6 * cw)
|
||||||
h.resizeSection(4, 16*cw)
|
h.resizeSection(4, 16 * cw)
|
||||||
h.resizeSection(5, 30*cw)
|
h.resizeSection(5, 30 * cw)
|
||||||
h.resizeSection(6, 20*cw)
|
h.resizeSection(6, 20 * cw)
|
||||||
h.resizeSection(7, 20*cw)
|
h.resizeSection(7, 20 * cw)
|
||||||
|
|
||||||
def set_model(self, model):
|
def set_model(self, model):
|
||||||
self.table_model = model
|
self.table_model = model
|
||||||
|
@ -143,7 +142,7 @@ class ScheduleDock(QtWidgets.QDockWidget):
|
||||||
selected_rid = self.table_model.row_to_key[row]
|
selected_rid = self.table_model.row_to_key[row]
|
||||||
pipeline = self.table_model.backing_store[selected_rid]["pipeline"]
|
pipeline = self.table_model.backing_store[selected_rid]["pipeline"]
|
||||||
logger.info("Requesting termination of all "
|
logger.info("Requesting termination of all "
|
||||||
"experiments in pipeline '%s'", pipeline)
|
"experiments in pipeline '%s'", pipeline)
|
||||||
|
|
||||||
rids = set()
|
rids = set()
|
||||||
for rid, info in self.table_model.backing_store.items():
|
for rid, info in self.table_model.backing_store.items():
|
||||||
|
@ -151,7 +150,6 @@ class ScheduleDock(QtWidgets.QDockWidget):
|
||||||
rids.add(rid)
|
rids.add(rid)
|
||||||
asyncio.ensure_future(self.request_term_multiple(rids))
|
asyncio.ensure_future(self.request_term_multiple(rids))
|
||||||
|
|
||||||
|
|
||||||
def save_state(self):
|
def save_state(self):
|
||||||
return bytes(self.table.horizontalHeader().saveState())
|
return bytes(self.table.horizontalHeader().saveState())
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ class ShortcutsDock(QtWidgets.QDockWidget):
|
||||||
for i in range(12):
|
for i in range(12):
|
||||||
row = i + 1
|
row = i + 1
|
||||||
|
|
||||||
layout.addWidget(QtWidgets.QLabel("F" + str(i+1)), row, 0)
|
layout.addWidget(QtWidgets.QLabel("F" + str(i + 1)), row, 0)
|
||||||
|
|
||||||
label = QtWidgets.QLabel()
|
label = QtWidgets.QLabel()
|
||||||
label.setSizePolicy(QtWidgets.QSizePolicy.Ignored,
|
label.setSizePolicy(QtWidgets.QSizePolicy.Ignored,
|
||||||
|
@ -68,7 +68,7 @@ class ShortcutsDock(QtWidgets.QDockWidget):
|
||||||
"open": open,
|
"open": open,
|
||||||
"submit": submit
|
"submit": submit
|
||||||
}
|
}
|
||||||
shortcut = QtWidgets.QShortcut("F" + str(i+1), main_window)
|
shortcut = QtWidgets.QShortcut("F" + str(i + 1), main_window)
|
||||||
shortcut.setContext(QtCore.Qt.ApplicationShortcut)
|
shortcut.setContext(QtCore.Qt.ApplicationShortcut)
|
||||||
shortcut.activated.connect(partial(self._activated, i))
|
shortcut.activated.connect(partial(self._activated, i))
|
||||||
|
|
||||||
|
|
|
@ -500,7 +500,7 @@ pub extern fn main() -> i32 {
|
||||||
println!(r"|_| |_|_|____/ \___/ \____|");
|
println!(r"|_| |_|_|____/ \___/ \____|");
|
||||||
println!("");
|
println!("");
|
||||||
println!("MiSoC Bootloader");
|
println!("MiSoC Bootloader");
|
||||||
println!("Copyright (c) 2017-2023 M-Labs Limited");
|
println!("Copyright (c) 2017-2024 M-Labs Limited");
|
||||||
println!("");
|
println!("");
|
||||||
|
|
||||||
#[cfg(has_ethmac)]
|
#[cfg(has_ethmac)]
|
||||||
|
|
|
@ -226,8 +226,8 @@ def main():
|
||||||
smgr.register(d_applets)
|
smgr.register(d_applets)
|
||||||
broadcast_clients["ccb"].notify_cbs.append(d_applets.ccb_notify)
|
broadcast_clients["ccb"].notify_cbs.append(d_applets.ccb_notify)
|
||||||
|
|
||||||
d_ttl_dds = moninj.MonInj(rpc_clients["schedule"])
|
d_moninj = moninj.MonInjDock(rpc_clients["schedule"])
|
||||||
atexit_register_coroutine(d_ttl_dds.stop, loop=loop)
|
atexit_register_coroutine(d_moninj.stop, loop=loop)
|
||||||
|
|
||||||
d_waveform = waveform.WaveformDock(
|
d_waveform = waveform.WaveformDock(
|
||||||
args.analyzer_proxy_timeout,
|
args.analyzer_proxy_timeout,
|
||||||
|
@ -237,10 +237,10 @@ def main():
|
||||||
atexit_register_coroutine(d_waveform.stop, loop=loop)
|
atexit_register_coroutine(d_waveform.stop, loop=loop)
|
||||||
|
|
||||||
def init_cbs(ddb):
|
def init_cbs(ddb):
|
||||||
d_ttl_dds.dm.init_ddb(ddb)
|
d_moninj.dm.init_ddb(ddb)
|
||||||
d_waveform.init_ddb(ddb)
|
d_waveform.init_ddb(ddb)
|
||||||
return ddb
|
return ddb
|
||||||
devices_sub = Subscriber("devices", init_cbs, [d_ttl_dds.dm.notify_ddb, d_waveform.notify_ddb])
|
devices_sub = Subscriber("devices", init_cbs, [d_moninj.dm.notify_ddb, d_waveform.notify_ddb])
|
||||||
loop.run_until_complete(devices_sub.connect(args.server, args.port_notify))
|
loop.run_until_complete(devices_sub.connect(args.server, args.port_notify))
|
||||||
atexit_register_coroutine(devices_sub.close, loop=loop)
|
atexit_register_coroutine(devices_sub.close, loop=loop)
|
||||||
|
|
||||||
|
@ -260,8 +260,7 @@ def main():
|
||||||
|
|
||||||
# lay out docks
|
# lay out docks
|
||||||
right_docks = [
|
right_docks = [
|
||||||
d_explorer, d_shortcuts,
|
d_explorer, d_shortcuts, d_moninj,
|
||||||
d_ttl_dds.ttl_dock, d_ttl_dds.dds_dock, d_ttl_dds.dac_dock,
|
|
||||||
d_datasets, d_applets, d_waveform, d_interactive_args
|
d_datasets, d_applets, d_waveform, d_interactive_args
|
||||||
]
|
]
|
||||||
main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, right_docks[0])
|
main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, right_docks[0])
|
||||||
|
@ -280,8 +279,7 @@ def main():
|
||||||
atexit_register_coroutine(smgr.stop, loop=loop)
|
atexit_register_coroutine(smgr.stop, loop=loop)
|
||||||
|
|
||||||
# work around for https://github.com/m-labs/artiq/issues/1307
|
# work around for https://github.com/m-labs/artiq/issues/1307
|
||||||
d_ttl_dds.ttl_dock.show()
|
d_moninj.show()
|
||||||
d_ttl_dds.dds_dock.show()
|
|
||||||
|
|
||||||
# create first log dock if not already in state
|
# create first log dock if not already in state
|
||||||
d_log0 = logmgr.first_log_dock()
|
d_log0 = logmgr.first_log_dock()
|
||||||
|
|
|
@ -202,7 +202,6 @@ class EnumerationEntry(QtWidgets.QWidget):
|
||||||
|
|
||||||
def __init__(self, argument):
|
def __init__(self, argument):
|
||||||
QtWidgets.QWidget.__init__(self)
|
QtWidgets.QWidget.__init__(self)
|
||||||
disable_scroll_wheel(self)
|
|
||||||
layout = QtWidgets.QHBoxLayout()
|
layout = QtWidgets.QHBoxLayout()
|
||||||
self.setLayout(layout)
|
self.setLayout(layout)
|
||||||
procdesc = argument["desc"]
|
procdesc = argument["desc"]
|
||||||
|
@ -221,6 +220,7 @@ class EnumerationEntry(QtWidgets.QWidget):
|
||||||
self.btn_group.idClicked.connect(submit)
|
self.btn_group.idClicked.connect(submit)
|
||||||
else:
|
else:
|
||||||
self.combo_box = QtWidgets.QComboBox()
|
self.combo_box = QtWidgets.QComboBox()
|
||||||
|
disable_scroll_wheel(self.combo_box)
|
||||||
self.combo_box.addItems(choices)
|
self.combo_box.addItems(choices)
|
||||||
idx = choices.index(argument["state"])
|
idx = choices.index(argument["state"])
|
||||||
self.combo_box.setCurrentIndex(idx)
|
self.combo_box.setCurrentIndex(idx)
|
||||||
|
|
|
@ -28,10 +28,10 @@ from artiq.master.worker_db import DeviceManager, DatasetManager, DummyDevice
|
||||||
from artiq.language.environment import (
|
from artiq.language.environment import (
|
||||||
is_public_experiment, TraceArgumentManager, ProcessArgumentManager
|
is_public_experiment, TraceArgumentManager, ProcessArgumentManager
|
||||||
)
|
)
|
||||||
from artiq.language.core import set_watchdog_factory, TerminationRequested
|
from artiq.language.core import host_only, set_watchdog_factory, TerminationRequested
|
||||||
from artiq.language.types import TBool
|
from artiq.language.types import TBool
|
||||||
from artiq.compiler import import_cache
|
from artiq.compiler import import_cache
|
||||||
from artiq.coredevice.core import CompileError, host_only, _render_diagnostic
|
from artiq.coredevice.core import CompileError, _render_diagnostic
|
||||||
from artiq import __version__ as artiq_version
|
from artiq import __version__ as artiq_version
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ master_doc = 'index'
|
||||||
|
|
||||||
# General information about the project.
|
# General information about the project.
|
||||||
project = 'ARTIQ'
|
project = 'ARTIQ'
|
||||||
copyright = '2014-2023, M-Labs Limited'
|
copyright = '2014-2024, M-Labs Limited'
|
||||||
|
|
||||||
# The version info for the project you're documenting, acts as replacement for
|
# The version info for the project you're documenting, acts as replacement for
|
||||||
# |version| and |release|, also used in various other places throughout the
|
# |version| and |release|, also used in various other places throughout the
|
||||||
|
|
|
@ -27,4 +27,4 @@ Website: https://m-labs.hk/artiq
|
||||||
|
|
||||||
`Cite ARTIQ <http://dx.doi.org/10.5281/zenodo.51303>`_ as ``Bourdeauducq, Sébastien et al. (2016). ARTIQ 1.0. Zenodo. 10.5281/zenodo.51303``.
|
`Cite ARTIQ <http://dx.doi.org/10.5281/zenodo.51303>`_ as ``Bourdeauducq, Sébastien et al. (2016). ARTIQ 1.0. Zenodo. 10.5281/zenodo.51303``.
|
||||||
|
|
||||||
Copyright (C) 2014-2023 M-Labs Limited. Licensed under GNU LGPL version 3+.
|
Copyright (C) 2014-2024 M-Labs Limited. Licensed under GNU LGPL version 3+.
|
||||||
|
|
Loading…
Reference in New Issue