Get started

Getting started with Q-CTRL BOULDER OPAL

The Q-CTRL Python package provides an intuitive and convenient Python interface to Q-CTRL’s quantum control solutions for customers of Q-CTRL.


  • To use the Q-CTRL Python package you will need a Q-CTRL account
  • The Q-CTRL Python package requires Python 3.6.4 or later, Python 3.7 or Python 3.8


To get started quickly and easily, we recommend Anaconda — a free and open-source distribution of the Python and R programming languages for scientific computing that aims to simplify package management and deployment.

Once you're set up with a valid Python version, run the following command in your terminal application:

$ pip install qctrl

Several of the BOULDER OPAL User guides and Application notes use the Q-CTRL Python Visualizer and Q-CTRL Python Open Controls packages, which you can install by running:

$ pip install qctrl-visualizer qctrl-open-controls


If you already have the qctrl package installed and wish to upgrade to the latest version, run:

$ pip install --upgrade qctrl

You can similarly upgrade the qctrl-visualizer and qctrl-open-controls packages.


To authenticate, you will need the email and password used to create your Q-CTRL account. You can use the following command to see all qctrl authentication options:

$ qctrl auth --help

Interactive authentication

The interactive authentication method is a command line utility that authenticates your credentials and saves an authentication file that gets used in all future interactions with the Python package.

This utility can be invoked from the terminal as follows:

$ qctrl auth

If you would like to store the automatically generated authentication file in a different place to the default location, you can do so through the use of the path command.

$ qctrl auth --path <your_custom_path>

The interactive authentication method can also be invoked using Python as shown below:

$ python
>>> from qctrl import Qctrl
>>> qctrl = Qctrl()

    This is an interactive Q-CTRL Authentication setup tool.

    For non-interactive or alternative options check our help:

        $ qctrl auth --help


Authenticating to
Successfully authenticated!
Authentication file created at /Users/me/.config/qctrl/99a605c91232cda79437e2908bdf0837

Note: You only need to do the above once. Subsequent invocations of Qctrl() will use the created authentication file.

Non-interactive authentication

For usage when interactive authentication is not available, you can authenticate by providing your credentials to the Qctrl() object as shown below.

$ python
>>> from qctrl import Qctrl
>>> qctrl = Qctrl(email='', password='mypassword')

Performing computations

Once you have the requirements installed and authentication set up, you can start to perform computations with the Q-CTRL Python package.

Imports and initialization

All usage of the Q-CTRL Python package begins by importing the qctrl package and starting a session.

import attr
import numpy as np

from qctrl import Qctrl

# Starting a session with the API
qctrl = Qctrl()

Creating objects

To perform computations using the Q-CTRL Python package you use functions, available in the qctrl.functions namespace. Functions compute outputs based on the inputs you provide. You provide the inputs to functions as objects, as defined in the qctrl.types namespace. Some objects are shared between functions, while some are specific to each function. You can also pass dictionaries instead of objects, which can be convenient for simple objects.

Below we show how to create input drive and shift objects for a filter function calculation (see the Filter functions user guide for details on the filter function calculation).

# Create drive segment object, and use it to create a drive object
drive_segment = qctrl.types.ComplexSegmentInput(duration=1, value=1 + 1j)
drive = qctrl.types.filter_function.Drive(
    operator=np.array([[0, 1], [0, 0]]),

# Create shift segment dictionary, and use it to create a shift object
shift_segment = {"duration": 1, "value": 2}
shift = qctrl.types.filter_function.Shift(
    operator=np.array([[1, 0], [0, -1]]),

Calling functions

Once you have created input objects (or dictionaries), you are ready to call a function that performs a computation based on the inputs you provide.

Here we show how to calculate a filter function, using the qctrl.functions.calculate_filter_function function.

filter_function_result = qctrl.functions.calculate_filter_function(
    frequencies=np.linspace(0, 1e6, 100),
100%|██████████| 100/100 [00:03<00:00, 32.32it/s]

Extracting results

Each function in the Q-CTRL Python package returns a standard Python object containing the computed data. Below we show a simple example of how to extract such data, and how to convert the data into a dictionary using the attr.asdict function, which can be useful when passing the computed data to other libraries.

print("Sample object:")
print("Sample dictionary:")
Sample object:
Sample(frequency=0.0, inverse_power=2.757165592732947, inverse_power_uncertainty=0.0, frequency_domain_noise_operator=array([[ 1.19961263-5.27350364e-17j,  0.93613575+6.64638976e-01j],
       [ 0.93613575-6.64638976e-01j, -1.19961263+5.27350364e-17j]]))

Sample dictionary:
{'frequency': 0.0, 'inverse_power': 2.757165592732947, 'inverse_power_uncertainty': 0.0, 'frequency_domain_noise_operator': array([[ 1.19961263-5.27350364e-17j,  0.93613575+6.64638976e-01j],
       [ 0.93613575-6.64638976e-01j, -1.19961263+5.27350364e-17j]])}

Extracting metadata

The functions from the Q-CTRL Python package also return an action object that contains metadata about its execution. Currently the main useful piece of metadata is the status value, which gives information about how the function terminated. More metadata will be populated in the action object in a future release.



We have shown the general procedure for setting up Python objects representing the input to a computation, passing these objects to a function in the Q-CTRL Python package, and extracting data from the result. The other user guides explain the specific inputs and outputs of each function in more detail. You can also visit the reference documentation to see the full details of all functions and types in the Q-CTRL Python package.