Skip to content

Commit f6800bd

Browse files
committed
Merge branch 'master' into nac3
2 parents e93d4aa + 6698a6f commit f6800bd

File tree

112 files changed

+3054
-2395
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

112 files changed

+3054
-2395
lines changed

README.rst

+7-11
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,18 @@
77
ARTIQ (Advanced Real-Time Infrastructure for Quantum physics) is a leading-edge control and data acquisition system for quantum information experiments.
88
It is maintained and developed by `M-Labs <https://m-labs.hk>`_ and the initial development was for and in partnership with the `Ion Storage Group at NIST <https://www.nist.gov/pml/time-and-frequency-division/ion-storage>`_. ARTIQ is free software and offered to the entire research community as a solution equally applicable to other challenging control tasks, including outside the field of ion trapping. Many laboratories around the world have adopted ARTIQ as their control system and some have `contributed <https://m-labs.hk/experiment-control/funding/>`_ to it.
99

10-
The system features a high-level programming language that helps describing complex experiments, which is compiled and executed on dedicated hardware with nanosecond timing resolution and sub-microsecond latency. It includes graphical user interfaces to parametrize and schedule experiments and to visualize and explore the results.
10+
The system features a high-level programming language, capable of describing complex experiments, which is compiled and executed on dedicated hardware with nanosecond timing resolution and sub-microsecond latency. It includes graphical user interfaces to parametrize and schedule experiments and to visualize and explore the results.
1111

12-
ARTIQ uses FPGA hardware to perform its time-critical tasks. The `Sinara hardware <https://github.com/sinara-hw>`_, and in particular the Kasli FPGA carrier, is designed to work with ARTIQ.
13-
ARTIQ is designed to be portable to hardware platforms from different vendors and FPGA manufacturers.
14-
Several different configurations of a `FPGA evaluation kit <https://www.xilinx.com/products/boards-and-kits/ek-k7-kc705-g.html>`_ and of a `Zynq evaluation kit <https://www.xilinx.com/products/boards-and-kits/ek-z7-zc706-g.html>`_ are also used and supported. FPGA platforms can be combined with any number of additional peripherals, either already accessible from ARTIQ or made accessible with little effort.
12+
ARTIQ uses FPGA hardware to perform its time-critical tasks. The `Sinara hardware <https://github.com/sinara-hw>`_, and in particular the Kasli FPGA carrier, are designed to work with ARTIQ. ARTIQ is designed to be portable to hardware platforms from different vendors and FPGA manufacturers. Several different configurations of a `FPGA evaluation kit <https://www.xilinx.com/products/boards-and-kits/ek-k7-kc705-g.html>`_ and a `Zynq evaluation kit <https://www.xilinx.com/products/boards-and-kits/ek-z7-zc706-g.html>`_ are also used and supported. FPGA platforms can be combined with any number of additional peripherals, either already accessible from ARTIQ or made accessible with little effort.
1513

16-
ARTIQ and its dependencies are available in the form of Nix packages (for Linux) and MSYS2 packages (for Windows). See `the manual <https://m-labs.hk/experiment-control/resources/>`_ for installation instructions.
17-
Packages containing pre-compiled binary images to be loaded onto the hardware platforms are supplied for each configuration.
18-
Like any open source software ARTIQ can equally be built and installed directly from `source <https://github.com/m-labs/artiq>`_.
14+
ARTIQ and its dependencies are available in the form of Nix packages (for Linux) and MSYS2 packages (for Windows). See `the manual <https://m-labs.hk/experiment-control/resources/>`_ for installation instructions. Packages containing pre-compiled binary images to be loaded onto the hardware platforms are supplied for each configuration. Like any open-source software ARTIQ can equally be built and installed directly from `source <https://github.com/m-labs/artiq>`_.
1915

20-
ARTIQ is supported by M-Labs and developed openly.
21-
Components, features, fixes, improvements, and extensions are often `funded <https://m-labs.hk/experiment-control/funding/>`_ by and developed for the partnering research groups.
16+
ARTIQ is supported by M-Labs and developed openly. Components, features, fixes, improvements, and extensions are often `funded <https://m-labs.hk/experiment-control/funding/>`_ by and developed for the partnering research groups.
2217

23-
Core technologies employed include `Python <https://www.python.org/>`_, `Migen <https://github.com/m-labs/migen>`_, `Migen-AXI <https://github.com/peteut/migen-axi>`_, `Rust <https://www.rust-lang.org/>`_, `MiSoC <https://github.com/m-labs/misoc>`_/`VexRiscv <https://github.com/SpinalHDL/VexRiscv>`_, `LLVM <https://llvm.org/>`_/`llvmlite <https://github.com/numba/llvmlite>`_, and `Qt5 <https://www.qt.io/>`_.
18+
Core technologies employed include `Python <https://www.python.org/>`_, `Migen <https://github.com/m-labs/migen>`_, `Migen-AXI <https://github.com/peteut/migen-axi>`_, `Rust <https://www.rust-lang.org/>`_, `MiSoC <https://github.com/m-labs/misoc>`_/`VexRiscv <https://github.com/SpinalHDL/VexRiscv>`_, `LLVM <https://llvm.org/>`_/`llvmlite <https://github.com/numba/llvmlite>`_, and `Qt6 <https://www.qt.io/>`_.
2419

25-
Website: https://m-labs.hk/artiq
20+
| Website: https://m-labs.hk/experiment-control/artiq
21+
| (US-hosted mirror: https://m-labs-intl.com/experiment-control/artiq)
2622
2723
`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``.
2824

RELEASE_NOTES.rst

+12-1
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,20 @@
33
Release notes
44
=============
55

6-
ARTIQ-8 (Unreleased)
6+
ARTIQ-9 (Unreleased)
77
--------------------
88

9+
* Zotino monitoring in the dashboard now displays the values in volts.
10+
* afws_client now uses the "happy eyeballs" algorithm (RFC 6555) for a faster and more
11+
reliable connection to the server.
12+
* The Zadig driver installer was added to the MSYS2 offline installer.
13+
* Fastino monitoring with Moninj is now supported.
14+
* Qt6 support.
15+
* Python 3.12 support.
16+
17+
ARTIQ-8
18+
-------
19+
920
Highlights:
1021

1122
* New hardware support:

artiq/applets/big_number.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env python3
22

3-
from PyQt5 import QtWidgets, QtCore, QtGui
3+
from PyQt6 import QtWidgets, QtCore, QtGui
44
from artiq.applets.simple import SimpleApplet
55
from artiq.tools import scale_from_metadata
66
from artiq.gui.tools import LayoutWidget
@@ -17,7 +17,7 @@ class QCancellableLineEdit(QtWidgets.QLineEdit):
1717
editCancelled = QtCore.pyqtSignal()
1818

1919
def keyPressEvent(self, event):
20-
if event.key() == QtCore.Qt.Key_Escape:
20+
if event.key() == QtCore.Qt.Key.Key_Escape:
2121
self.editCancelled.emit()
2222
else:
2323
super().keyPressEvent(event)
@@ -44,7 +44,7 @@ def __init__(self, args, req):
4444

4545
self.edit_widget = QCancellableLineEdit()
4646
self.edit_widget.setValidator(QtGui.QDoubleValidator())
47-
self.edit_widget.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignVCenter)
47+
self.edit_widget.setAlignment(QtCore.Qt.AlignmentFlag.AlignRight | QtCore.Qt.AlignmentFlag.AlignVCenter)
4848
self.edit_widget.editCancelled.connect(self.cancel_edit)
4949
self.edit_widget.returnPressed.connect(self.confirm_edit)
5050
self.number_area.addWidget(self.edit_widget)

artiq/applets/image.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env python3
22

3-
import PyQt5 # make sure pyqtgraph imports Qt5
3+
import PyQt6 # make sure pyqtgraph imports Qt6
44
import pyqtgraph
55

66
from artiq.applets.simple import SimpleApplet

artiq/applets/plot_hist.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env python3
22

3-
import PyQt5 # make sure pyqtgraph imports Qt5
4-
from PyQt5.QtCore import QTimer
3+
import PyQt6 # make sure pyqtgraph imports Qt6
4+
from PyQt6.QtCore import QTimer
55
import pyqtgraph
66

77
from artiq.applets.simple import TitleApplet

artiq/applets/plot_xy.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#!/usr/bin/env python3
22

33
import numpy as np
4-
import PyQt5 # make sure pyqtgraph imports Qt5
5-
from PyQt5.QtCore import QTimer
4+
import PyQt6 # make sure pyqtgraph imports Qt6
5+
from PyQt6.QtCore import QTimer
66
import pyqtgraph
77

88
from artiq.applets.simple import TitleApplet

artiq/applets/plot_xy_hist.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#!/usr/bin/env python3
22

33
import numpy as np
4-
from PyQt5 import QtWidgets
5-
from PyQt5.QtCore import QTimer
4+
from PyQt6 import QtWidgets
5+
from PyQt6.QtCore import QTimer
66
import pyqtgraph
77

88
from artiq.applets.simple import SimpleApplet

artiq/applets/progress_bar.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env python3
22

3-
from PyQt5 import QtWidgets
3+
from PyQt6 import QtWidgets
44

55
from artiq.applets.simple import SimpleApplet
66

artiq/applets/simple.py

+14-13
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,21 @@ def __init__(self):
2424
def set_dataset(self, key, value, unit=None, scale=None, precision=None, persist=None):
2525
"""
2626
Set a dataset.
27-
See documentation of ``artiq.language.environment.set_dataset``.
27+
See documentation of :meth:`~artiq.language.environment.HasEnvironment.set_dataset`.
2828
"""
2929
raise NotImplementedError
3030

3131
def mutate_dataset(self, key, index, value):
3232
"""
3333
Mutate a dataset.
34-
See documentation of ``artiq.language.environment.mutate_dataset``.
34+
See documentation of :meth:`~artiq.language.environment.HasEnvironment.mutate_dataset`.
3535
"""
3636
raise NotImplementedError
3737

3838
def append_to_dataset(self, key, value):
3939
"""
4040
Append to a dataset.
41-
See documentation of ``artiq.language.environment.append_to_dataset``.
41+
See documentation of :meth:`~artiq.language.environment.HasEnvironment.append_to_dataset`.
4242
"""
4343
raise NotImplementedError
4444

@@ -49,8 +49,9 @@ def set_argument_value(self, expurl, key, value):
4949
5050
:param expurl: Experiment URL identifying the experiment in the dashboard. Example: 'repo:ArgumentsDemo'.
5151
:param key: Name of the argument in the experiment.
52-
:param value: Object representing the new temporary value of the argument. For ``Scannable`` arguments, this parameter
53-
should be a ``ScanObject``. The type of the ``ScanObject`` will be set as the selected type when this function is called.
52+
:param value: Object representing the new temporary value of the argument. For :class:`~artiq.language.scan.Scannable` arguments,
53+
this parameter should be a :class:`~artiq.language.scan.ScanObject`. The type of the :class:`~artiq.language.scan.ScanObject`
54+
will be set as the selected type when this function is called.
5455
"""
5556
raise NotImplementedError
5657

@@ -136,9 +137,8 @@ async def embed(self, win_id):
136137
logger.error("unexpected action reply to embed request: %s",
137138
reply["action"])
138139
self.close_cb()
139-
140-
def fix_initial_size(self):
141-
self.write_pyon({"action": "fix_initial_size"})
140+
else:
141+
return reply["size_w"], reply["size_h"]
142142

143143
async def listen(self):
144144
data = None
@@ -272,7 +272,7 @@ def create_main_widget(self):
272272
# HACK: if the window has a frame, there will be garbage
273273
# (usually white) displayed at its right and bottom borders
274274
# after it is embedded.
275-
self.main_widget.setWindowFlags(QtCore.Qt.FramelessWindowHint)
275+
self.main_widget.setWindowFlags(QtCore.Qt.WindowType.FramelessWindowHint)
276276
self.main_widget.show()
277277
win_id = int(self.main_widget.winId())
278278
self.loop.run_until_complete(self.ipc.embed(win_id))
@@ -285,12 +285,13 @@ def create_main_widget(self):
285285
# 2. applet creates native window without showing it, and
286286
# gets its ID
287287
# 3. applet sends the ID to host, host embeds the widget
288-
# 4. applet shows the widget
289-
# 5. parent resizes the widget
288+
# and returns embedded size
289+
# 4. applet is resized to that given size
290+
# 5. applet shows the widget
290291
win_id = int(self.main_widget.winId())
291-
self.loop.run_until_complete(self.ipc.embed(win_id))
292+
size_w, size_h = self.loop.run_until_complete(self.ipc.embed(win_id))
293+
self.main_widget.resize(size_w, size_h)
292294
self.main_widget.show()
293-
self.ipc.fix_initial_size()
294295
else:
295296
self.main_widget.show()
296297

artiq/browser/datasets.py

+11-10
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import logging
22
import asyncio
33

4-
from PyQt5 import QtCore, QtWidgets
4+
from PyQt6 import QtCore, QtGui, QtWidgets
55

66
from sipyco.pc_rpc import AsyncioClient as RPCClient
77

88
from artiq.tools import short_format
9-
from artiq.gui.tools import LayoutWidget, QRecursiveFilterProxyModel
9+
from artiq.gui.tools import LayoutWidget
1010
from artiq.gui.models import DictSyncTreeSepModel
1111

1212
# reduced read-only version of artiq.dashboard.datasets
@@ -62,8 +62,8 @@ class DatasetsDock(QtWidgets.QDockWidget):
6262
def __init__(self, dataset_sub, dataset_ctl):
6363
QtWidgets.QDockWidget.__init__(self, "Datasets")
6464
self.setObjectName("Datasets")
65-
self.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable |
66-
QtWidgets.QDockWidget.DockWidgetFloatable)
65+
self.setFeatures(self.DockWidgetFeature.DockWidgetMovable |
66+
self.DockWidgetFeature.DockWidgetFloatable)
6767

6868
grid = LayoutWidget()
6969
self.setWidget(grid)
@@ -74,9 +74,9 @@ def __init__(self, dataset_sub, dataset_ctl):
7474
grid.addWidget(self.search, 0, 0)
7575

7676
self.table = QtWidgets.QTreeView()
77-
self.table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
77+
self.table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows)
7878
self.table.setSelectionMode(
79-
QtWidgets.QAbstractItemView.SingleSelection)
79+
QtWidgets.QAbstractItemView.SelectionMode.SingleSelection)
8080
grid.addWidget(self.table, 1, 0)
8181

8282
metadata_grid = LayoutWidget()
@@ -85,13 +85,13 @@ def __init__(self, dataset_sub, dataset_ctl):
8585
"rid start_time".split()):
8686
metadata_grid.addWidget(QtWidgets.QLabel(label), i, 0)
8787
v = QtWidgets.QLabel()
88-
v.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse)
88+
v.setTextInteractionFlags(QtCore.Qt.TextInteractionFlag.TextSelectableByMouse)
8989
metadata_grid.addWidget(v, i, 1)
9090
self.metadata[label] = v
9191
grid.addWidget(metadata_grid, 2, 0)
9292

93-
self.table.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)
94-
upload_action = QtWidgets.QAction("Upload dataset to master",
93+
self.table.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.ActionsContextMenu)
94+
upload_action = QtGui.QAction("Upload dataset to master",
9595
self.table)
9696
upload_action.triggered.connect(self.upload_clicked)
9797
self.table.addAction(upload_action)
@@ -112,7 +112,8 @@ def metadata_changed(self, new):
112112

113113
def set_model(self, model):
114114
self.table_model = model
115-
self.table_model_filter = QRecursiveFilterProxyModel()
115+
self.table_model_filter = QtCore.QSortFilterProxyModel()
116+
self.table_model_filter.setRecursiveFilteringEnabled(True)
116117
self.table_model_filter.setSourceModel(self.table_model)
117118
self.table.setModel(self.table_model_filter)
118119

artiq/browser/experiments.py

+12-12
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from functools import partial
55
from collections import OrderedDict
66

7-
from PyQt5 import QtCore, QtGui, QtWidgets
7+
from PyQt6 import QtCore, QtGui, QtWidgets
88
import h5py
99

1010
from sipyco import pyon
@@ -33,13 +33,13 @@ def __init__(self, dock):
3333
recompute_arguments = QtWidgets.QPushButton("Recompute all arguments")
3434
recompute_arguments.setIcon(
3535
QtWidgets.QApplication.style().standardIcon(
36-
QtWidgets.QStyle.SP_BrowserReload))
36+
QtWidgets.QStyle.StandardPixmap.SP_BrowserReload))
3737
recompute_arguments.clicked.connect(self._recompute_arguments_clicked)
3838

3939
load = QtWidgets.QPushButton("Set arguments from HDF5")
4040
load.setToolTip("Set arguments from currently selected HDF5 file")
4141
load.setIcon(QtWidgets.QApplication.style().standardIcon(
42-
QtWidgets.QStyle.SP_DialogApplyButton))
42+
QtWidgets.QStyle.StandardPixmap.SP_DialogApplyButton))
4343
load.clicked.connect(self._load_clicked)
4444

4545
buttons = LayoutWidget()
@@ -86,7 +86,7 @@ def __init__(self, area, expurl, arguments):
8686
self.resize(100*qfm.averageCharWidth(), 30*qfm.lineSpacing())
8787
self.setWindowTitle(expurl)
8888
self.setWindowIcon(QtWidgets.QApplication.style().standardIcon(
89-
QtWidgets.QStyle.SP_FileDialogContentsView))
89+
QtWidgets.QStyle.StandardPixmap.SP_FileDialogContentsView))
9090
self.setAcceptDrops(True)
9191

9292
self.layout = QtWidgets.QGridLayout()
@@ -126,22 +126,22 @@ def update_log_level(index):
126126

127127
run = QtWidgets.QPushButton("Analyze")
128128
run.setIcon(QtWidgets.QApplication.style().standardIcon(
129-
QtWidgets.QStyle.SP_DialogOkButton))
129+
QtWidgets.QStyle.StandardPixmap.SP_DialogOkButton))
130130
run.setToolTip("Run analysis stage (Ctrl+Return)")
131131
run.setShortcut("CTRL+RETURN")
132-
run.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
133-
QtWidgets.QSizePolicy.Expanding)
132+
run.setSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding,
133+
QtWidgets.QSizePolicy.Policy.Expanding)
134134
self.layout.addWidget(run, 2, 4)
135135
run.clicked.connect(self._run_clicked)
136136
self._run = run
137137

138138
terminate = QtWidgets.QPushButton("Terminate")
139139
terminate.setIcon(QtWidgets.QApplication.style().standardIcon(
140-
QtWidgets.QStyle.SP_DialogCancelButton))
140+
QtWidgets.QStyle.StandardPixmap.SP_DialogCancelButton))
141141
terminate.setToolTip("Terminate analysis (Ctrl+Backspace)")
142142
terminate.setShortcut("CTRL+BACKSPACE")
143-
terminate.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
144-
QtWidgets.QSizePolicy.Expanding)
143+
terminate.setSizePolicy(QtWidgets.QSizePolicy.Policy.Expanding,
144+
QtWidgets.QSizePolicy.Policy.Expanding)
145145
self.layout.addWidget(terminate, 3, 4)
146146
terminate.clicked.connect(self._terminate_clicked)
147147
terminate.setEnabled(False)
@@ -316,7 +316,7 @@ def dataset_activated(self, path):
316316
asyncio.ensure_future(sub.load_hdf5_task(path))
317317

318318
def mousePressEvent(self, ev):
319-
if ev.button() == QtCore.Qt.LeftButton:
319+
if ev.button() == QtCore.Qt.MouseButton.LeftButton:
320320
self.select_experiment()
321321

322322
def paintEvent(self, event):
@@ -406,7 +406,7 @@ def open_experiment(self, expurl, arguments):
406406
exc_info=True)
407407
dock = _ExperimentDock(self, expurl, {})
408408
asyncio.ensure_future(dock._recompute_arguments())
409-
dock.setAttribute(QtCore.Qt.WA_DeleteOnClose)
409+
dock.setAttribute(QtCore.Qt.WidgetAttribute.WA_DeleteOnClose)
410410
self.addSubWindow(dock)
411411
dock.show()
412412
dock.sigClosed.connect(partial(self.on_dock_closed, dock))

0 commit comments

Comments
 (0)