{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a594f261",
   "metadata": {},
   "source": [
    "# Get started with Boulder Opal autocalibration\n",
    "\n",
    "**Install Boulder Opal, configure your credentials, and create a client session ready for your first job**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a594body",
   "metadata": {},
   "source": [
    "Boulder Opal is Q-CTRL's orchestration layer for autonomous quantum hardware characterization and calibration. It provides a Python client that connects to local hardware systems and then interfaces to the Q-CTRL Cloud to access and run tailored and robust quantum control workflows. Before you can submit your first job, you need to install Boulder Opal in your Python environment, gather the credentials that authenticate you against the Q-CTRL Cloud, and instantiate the runtime and client that mediate every subsequent call.\n",
    "\n",
    "# Requirements\n",
    "\n",
    "* Python 3.11 or later\n",
    "* A Q-CTRL API key (contact your Q-CTRL account team if you do not have one)\n",
    "* Q-CTRL organization slug (`https://accounts.q-ctrl.com/organizations`)\n",
    "* Familiarity with running Jupyter notebooks and Python environments\n",
    "* Internet access"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d3983ef5",
   "metadata": {},
   "source": [
    "## 1. Setup\n",
    "\n",
    "Install Boulder Opal, authenticate with the Q-CTRL platform, and register your control\n",
    "hardware."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "de3f6894",
   "metadata": {},
   "source": [
    "Boulder Opal is distributed as a Python package named `boulderopalscaleup`. This single package gives you the client, runtime, and all experiment and routine types. Install it into the Python environment you intend to use for calibration work."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9f1fe8da",
   "metadata": {},
   "outputs": [],
   "source": [
    "%pip install boulder-opal-scale-up"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d7f752b7",
   "metadata": {},
   "source": [
    "## 2. Authenticate\n",
    "\n",
    "Create a `QctrlScaleUpClient` using your API key and organization slug. The client handles authentication, job submission, and result retrieval. Replace the placeholder strings below with your real credentials before running.\n",
    "\n",
    "Follow these steps to retrieve an existing API key or generate a new one:\n",
    "\n",
    "1. Login on Q-CTRL’s website\n",
    "2. Go to [Sign in and security](https://accounts.q-ctrl.com/security) within Account Settings\n",
    "3. In the API keys section, you can either use the existing auto-generated API key or create a new key by clicking on Create new API key.\n",
    "4. Copy your API key to your clipboard and paste it into your script.\n",
    "\n",
    "**Note:** For production workflows, store your API key in the `QCTRL_API_KEY` environment variable rather than hardcoding it in notebooks."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "773b8db6",
   "metadata": {},
   "outputs": [],
   "source": [
    "from boulderopalscaleup import QctrlScaleUpClient\n",
    "from boulderopalscaleup.runtime import Runtime\n",
    "\n",
    "api_key = \"<your-api-key>\"\n",
    "organization_slug = \"<your-org-slug>\"\n",
    "\n",
    "runtime = Runtime.new()\n",
    "\n",
    "client = QctrlScaleUpClient(\n",
    "    runtime=runtime, api_key=api_key, organization_slug=organization_slug\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8dbfbf53",
   "metadata": {},
   "source": [
    "## 3. Connect to your control hardware\n",
    "\n",
    "Before running experiments you register a runtime system that describes the control hardware connected to your QPU. The runtime exposes a backend-specific system info object for each supported control system; you instantiate it with the host, port, and any other connection details for your setup, and pass it to `runtime.add_system()`. From that point on, every experiment you submit is routed through the runtime to the appropriate controller without any further configuration on your side.\n",
    "\n",
    "The exact import path and constructor arguments depend on your backend:\n",
    "* To configure Boulder Opal for Quantum Machines controllers, use the [Quantum Machines setup guide](https://docs.q-ctrl.com/boulder-opal/autocalibration/discover/setting-up-boulder-opal-with-quantummachines-opx-controllers).\n",
    "* To configure Boulder Opal for Qblox controllers, use the [Qblox setup guide](https://docs.q-ctrl.com/boulder-opal/autocalibration/discover/setting-up-boulder-opal-with-qblox-controllers)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f3d8a91c",
   "metadata": {},
   "source": [
    "## 4. Verify the session\n",
    "\n",
    "Once the runtime is registered and the client is constructed, list the virtual devices registered under your organization to confirm that the credentials are accepted and the connection to the Q-CTRL platform is working. If you have not created any virtual devices yet, the listing is empty, which is expected. An error returned at this point indicates a problem with the API key, organization slug, or network access rather than with a specific device."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "a7e2d4b5",
   "metadata": {},
   "outputs": [],
   "source": [
    "devices = await client.get_devices()\n",
    "client.display(devices)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c9f1b3e8",
   "metadata": {},
   "source": [
    "## Next steps\n",
    "\n",
    "- [What is Boulder Opal?](https://docs.q-ctrl.com/boulder-opal/autocalibration/discover/what-is-boulder-opal): an overview of the virtual device, the workflow hierarchy, and the supported hardware.\n",
    "- [Creating your first virtual device with Boulder Opal](https://docs.q-ctrl.com/boulder-opal/autocalibration/discover/creating-your-first-virtual-device-with-boulder-opal): register a QPU configuration and set it as your active device.\n",
    "- [Running your first job with Boulder Opal](https://docs.q-ctrl.com/boulder-opal/autocalibration/discover/running-your-first-job-with-boulder-opal): submit a resonator spectroscopy experiment and retrieve the results."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.19"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
