# Boulder Opal Toolkits

**Simplify your workflows with convenience functions, nodes, and classes**

The Boulder Opal Toolkits, built on top of the existing Boulder Opal functions and graph operations, provide functions, nodes, and classes that enable you to develop and implement workflows faster and with less code, for a particular physical system or system-agnostic tasks.

The graph framework in Boulder Opal offers broad flexibility to represent quantum systems and desired computations on them, including simulation and optimization. The prebuilt functions, nodes and classes provided in the toolkits simplify some of the common workflows and tasks. For example, the Boulder Opal superconducting toolkit contains efficient functionalities to simulate and optimize superconducting qubit systems, and the pulse library provides various forms of commonly used control signals.

This topic will give you an overview of the Boulder Opal Toolkits that come as part of the Q-CTRL Python package. It will cover the three main kinds of toolkit operations:

- Functions that run Boulder Opal workflows of a particular physical system.
- Functions that perform system-agnostic tasks.
- Nodes that simplify graph construction.

**The Boulder Opal Toolkits are currently in beta phase of development. Breaking changes may be introduced.**

## System-specific toolkit functions

The toolkits designed for specific systems contain prebuilt functions that will allow you to set up simulation or optimization in a simpler and faster way.

The system-specific toolkit functions incorporate setting up a graph-based calculation, calling the required functions from Boulder Opal to perform the computations, and then returning the results.
These toolkit functions are imported the moment you start a session of Boulder Opal by instantiating the `Qctrl`

object, and they can be accessed from a namespace in the instantiated object.
For example, functions from the Boulder Opal superconducting toolkit can be accessed via `qctrl.superconducting`

, where `qctrl`

is an instance of the `Qctrl`

class.

These toolkit functions use your Boulder Opal session to call computations such as `qctrl.functions.calculate_optimization`

or `qctrl.functions.calculate_graph`

.
Examples of these include running a simulation or an optimization of a common quantum system such as a transmon coupled to a cavity.
These are tasks that you could perform using the Boulder Opal graph framework and standard numerical libraries, but which the toolkit functions wrap around, saving your time and speeding up development.

Some of the toolkit functions in the `qctrl`

object use dataclasses that allow you to store data about specific parts of your physical system, reflecting the physics of the problem in an intuitive way.
For example, the Boulder Opal superconducting toolkit allows you to describe the system in terms of familiar physical concepts such as `qctrl.superconducting.Transmon`

, `qctrl.superconducting.Cavity`

, and their mutual `qctrl.superconducting.TransmonCavityInteraction`

.
These dataclasses are used as building blocks and can be passed to `qctrl.superconducting.simulate`

and `qctrl.superconducting.optimize`

for system simulation or optimization

You can learn more about using the superconducting toolkit in our tutorial and you can find a complete list of the Boulder Opal Toolkits and their corresponding namespaces in the reference documentation for the toolkits.

## System-agnostic toolkit functions

System-agnostic toolkit functions are typically designed to perform trivial data manipulation or short calculations. This means that this type of function doesnâ€™t consume compute time from Boulder Opal and typically runs instantly.

These functions are usually found within the `qctrl.utils`

namespace of your instance of the `Qctrl`

object.
Examples include data conversion functions such as `qctrl.utils.pwc_pairs_to_arrays`

and statistical analysis functions such as `qctrl.utils.confidence_ellipse_matrix`

.
In both cases, the functions manipulate data that you already have available from calculation results, but organize them in a more convenient form.

## Toolkit graph operations

For situations where the system is not yet covered by a system-specific toolkit, or when you are experimenting with a Hamiltonian that has non-standard terms, you might benefit from customizing your system via graphs. Graphs offer a flexible way of communicating the structure of your custom model in Boulder Opal for simulation or optimization.

The Boulder Opal Toolkits also offer convenience graph operations, which wrap the functionality of several operations over graph tensors.
These toolkit operations are available as part of the `Graph`

object that you instantiate with the function `qctrl.create_graph`

.
You can access these operations via namespaces that group them according to their purpose, in the same way that the namespaces for the `Qctrl`

object work.
For example, if miscellaneous toolkit functions can be found in the `qctrl.utils`

namespace, then miscellaneous toolkit graph operations can be found in the `graph.utils`

namespace.

You can use the graph operations from the toolkit to simplify the setup of your graph.
For example, you can use the operation `graph.utils.real_optimizable_pwc_signal`

to create the optimization signal that can be passed to `qctrl.functions.calculate_optimization`

when you set up an optimization graph.
Or, if you want to use a predefined pulse as the basis for your optimization, you can import one from the `graph.pulses`

namespace.

You can find a complete list of the Boulder Opal Toolkits and their corresponding namespaces in the reference documentation for the toolkits. To learn more about the pulse toolkit specifically, visit the topic Libraries of pulses for Boulder Opal.