Quicker user guide
Introduction
This is a very condensed user guide meant to provide a quick start for you to create a Quantum Device Manager “device” service within the Juice OS.
It should create the blank “device” service first. After that, you will be introduced to an example of creating a lab initialization script to be run automatically whenever the service starts. Then it moves on to modifying the default orchestration.toml file to set up the database bucket for this service and configuring the device service to run the initialization script.
Housekeeping
These sequential set of instructions assume you have root access to the AlmaLinux distro, and have a basic linux admin ability (i.e. file copy and creation, terminal navigation).
The guide itself
-
Follow all the instructions for installation here ( Installation — OrangeQS Juice documentation )
-
Verify that you are able to connect to the default juice environment by navigating with a browser to “localhost:8888”. You should see a login page as shown below:
2a. Enter the login details for your AlmaLinux account.
2b. Once logged in, you should be seeing a similar starting page:
2c. Enter the Jupyterlab environment
2d. Edit the default pyproject.toml file within the shared/lib/lab/ directory as shown below to reflect the contents also shown within the image which installs the qcodes, quantify, pyvisa-py and pyserial dependencies on top of the orangeqs-juice-core packages. Save the changes.
2e. After that, create an init_device_service.py file within the shared/lib/lab/src/lab directory with the following content:
from __future__ import annotations
# ---------------
# basic imports
# ---------------
import time
# for benchmarking purposes
t0 = time.time()
import os
import sys
from pathlib import Path
from importlib import reload
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import display, SVG
import warnings
from typing import Optional, Any, Tuple
from qcodes import validators
from qcodes.instrument.base import Instrument
from qcodes.instrument.parameter import ManualParameter
warnings.filterwarnings("ignore")
t1 = time.time()
print(f"Finished basic imports {t1-t0:.2f} s")
class DummyFluxCurrent(Instrument):
"""A Dummy QCoDeS instrument for a current source."""
def __init__(self, name: str, channel_list: list[str]):
super().__init__(name)
for channel in channel_list:
self.add_parameter(
channel,
unit="A",
initial_value=0,
vals=validators.Numbers(),
parameter_class=ManualParameter,
)
class DummyVNA(Instrument):
"""A dummy VNA driver"""
def __init__(self, name: str):
super().__init__(name)
self.MAX_NPTS = 1001
# -------------------------------------------------------------------------------------------------
# Connect VNA
# -------------------------------------------------------------------------------------------------
try:
vna = DummyVNA(
name="vna",
)
print("Connected to VNA")
except Exception as e:
print("Something went wrong connecting to the vna:", e)
# -------------------------------------------------------------------------------------------------
# Connect FLUX
# -------------------------------------------------------------------------------------------------
try:
flux = DummyFluxCurrent(
name="flux",
channel_list=["output_1", "output_2", "output_3"]
)
print("Connected to current source")
except Exception as e:
print("Something went wrong connecting to the current source:", e)
t3 = time.time()
print(f"\nFinished loading settings {t3-t0:.2f} s")
This file will be used later in the construction of the orchestration.toml file.
- Open the AlmaLinux terminal. Turn on
root access by sudo -i and enter the credentials.
4a. Edit the default /etc/juice/config/orchestration.toml file to duplicate these entries:
# Add the lab extension to the default environment.
# This environment will be used by all services and singleuser containers unless overridden.
# See below for some examples.
[environments.default]
type = "uv"
dependencies = ["lab"]
sources = { lab = { editable = true, path = "~/shared/lib/lab" }}
# This entry creates a device service kernel
[services.device]
entrypoint = "orangeqs.juice.service:IPythonService"
# This entry tells the device service to run a python script called init_device_service.py within the shared/lab repo.
[services.device.init_kwargs]
init_module = "lab.init_device_service"
# This entry creates a service-device data bucket within the influxdb2 database service
[influxdb2.buckets.service-device]
name = "service-device"
## This entry sets any necessary environments for the device service container (e.g.) device port forwarding or volume mounts from hostOS to the service container.
[environments.device.envinronment]
type = "uv"
dependencies = ["lab"]
sources = { lab = { editable = true, path = "~/shared/lib/lab" }}
[services.device.environment.container]
volumes = [
"/etc/machine-id:/etc/machine-id:ro"
]
# Forward the device /dev/tty1 from AlmaLinux to the device service container device /dev/custom_6
devices = ["/dev/tty1:/dev/custom_6"]
group_add = ["dialout"]
The comments within the file should help explain the reasons why they’re there, especially about the device forwarding from AlmaLinux to the service container.
4b. As for the instruments to connect to, as long as the host OS (AlmaLinux) can ping to the device (this is assuming an ethernet connection with the instrument), then any service spawned will be able to connect to it.
-
After you’re done editing, run juice install --rebuild --restart --no-parallel-build. You should be able to see the output from the terminal after it has finished rebuilding and restarted.
-
Go to a web browser and navigate back to localhost:8888 to spawn the Jupyterlab environment. You should now be able to see an extra Service: device button within the Notebook and Console. These will spawn proxy kernels to send instructions directly to the device service kernel. For example, open up the Console for the device service.
-
You should be taken to a familiar ipython console which is behind the scenes has a proxy kernel which communicates with the device service. The user experience however does not change from your point of view. A simple dir() should tell you what objects are available in the device service kernel. If the init script was executed properly, you should be able to see the vna and flux qcodes instruments and are also able to print their respective snapshots from this same console as shown here:
-
And to further check that COM devices are forwarded correctly, do an !ls /dev/ within the same console. In the example orchestration.toml we deliberately forwarded the /dev/tty1 instrument from AlmaLinux to /dev/custom_6 instrument in the device service container. You should verify that the output is as shown below:
You now have a very basic Quantum Device Manager “device” service running within your JuiceOS installation.