{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "db14771b",
   "metadata": {},
   "source": [
    "# Quantinuum Quick Start\n",
    "\n",
    "This notebook walks you through running your first QESEM job on a Quantinuum system."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2f15dd1c",
   "metadata": {},
   "source": [
    "## Setup\n",
    "\n",
    "Install the Qedma client, import the relevant packages, and configure your Qedma client. See [Installation](../installation/#register-your-quantinuum-refresh-token) for more information."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7ecdf4df",
   "metadata": {},
   "outputs": [],
   "source": [
    "!pip install -U \"qedma-api[quantinuum]\" qiskit"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "2b53a695",
   "metadata": {},
   "outputs": [],
   "source": [
    "import qedma_api\n",
    "import qiskit\n",
    "import getpass\n",
    "import qnexus"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "99f1a5f6",
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_quantinuum_refresh_token():\n",
    "    qnexus.logout()\n",
    "    response = qnexus.client.get_nexus_client().post(\n",
    "        \"https://nexus.quantinuum.com/auth/login\",\n",
    "        json={\n",
    "            \"email\": input(\"Quantinuum email: \"),\n",
    "            \"password\": getpass.getpass(\"Quantinuum password: \"),\n",
    "        },\n",
    "    )\n",
    "    response.raise_for_status()\n",
    "\n",
    "    refresh_token = response.cookies.get(\"myqos_oat\")\n",
    "    if refresh_token is None:\n",
    "        raise RuntimeError(\"Quantinuum did not return a refresh token.\")\n",
    "    return refresh_token\n",
    "\n",
    "refresh_token = get_quantinuum_refresh_token()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b23d727c",
   "metadata": {},
   "outputs": [],
   "source": [
    "qedma_client = qedma_api.Client(api_token=\"<Qedma API token>\")\n",
    "qedma_client.unregister_qpu_token()\n",
    "qedma_client.register_qpu_token(token=refresh_token)\n",
    "\n",
    "provider = qedma_api.QuantinuumProvider()\n",
    "qedma_client.set_provider(provider)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7f9b2b6e",
   "metadata": {},
   "source": [
    "## Build a Circuit and Observables\n",
    "\n",
    "Create a circuit using Qiskit or pytket."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9401a3d1",
   "metadata": {},
   "outputs": [],
   "source": [
    "circuit = qiskit.QuantumCircuit(5)\n",
    "circuit.h(0)\n",
    "circuit.cx(0, 1)\n",
    "circuit.cx(1, 2)\n",
    "circuit.cx(2, 3)\n",
    "circuit.cx(3, 4)\n",
    "\n",
    "avg_magnetization = qiskit.quantum_info.SparsePauliOp.from_sparse_list(\n",
    "    [(\"Z\", [q], 1 / 5) for q in range(5)], num_qubits=5\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d0774299",
   "metadata": {},
   "source": [
    "## Create the Job\n",
    "\n",
    "The QESEM flow begins with `create_job(...)`. This step registers the workload, starts analytical estimation automatically, and returns a job identifier that can then be used to estimate the HQC cost of the empirical estimation and the remaining mitigation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8e34f1f7",
   "metadata": {},
   "outputs": [],
   "source": [
    "job = qedma_client.create_job(\n",
    "    circuit=circuit,\n",
    "    observables=[avg_magnetization],\n",
    "    observables_metadata=[\n",
    "        qedma_api.ObservableMetadata(description=\"Average magnetization\"),\n",
    "    ],\n",
    "    precision=0.05,\n",
    "    backend=\"H2-1E\",\n",
    "    description=\"quantinuum qesem quick start\",\n",
    "    enable_notifications=True,\n",
    ")\n",
    "\n",
    "print(job.job_id)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "64c6bdb7",
   "metadata": {},
   "source": [
    "<div class=\"admonition note\">\n",
    "    <p class=\"admonition-title\">Note</p>\n",
    "    <p style=\"padding-top:10px\">\n",
    "       The <code>precision</code> specifies the acceptable absolute error on the expectation values of the observables. QESEM continues mitigation until each input observable reaches the requested precision within a <code>1σ</code> confidence interval. The total HQC cost is the exact analytical-estimation cost for empirical estimation plus the HQC cost returned by empirical estimation.\n",
    "    </p>\n",
    "</div>\n",
    "\n",
    "<div class=\"admonition note\">\n",
    "    <p class=\"admonition-title\">Note</p>\n",
    "    <p style=\"padding-top:10px\">\n",
    "       When the QESEM job completes, an email notification is sent to the job creator. In some cases, the email might end up in the spam or quarantine folder. If that happens, mark the sender as trusted to prevent this in the future. To disable email notifications, set <code>enable_notifications=False</code> when creating the QESEM job.\n",
    "    </p>\n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d3c5c4a3",
   "metadata": {},
   "source": [
    "## Wait for Analytical Resource Estimation\n",
    "\n",
    "The analytical stage provides the exact HQC cost required for the empirical estimation pass."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f850a694",
   "metadata": {},
   "outputs": [],
   "source": [
    "analytical_estimation = qedma_client.wait_for_analytical_resource_estimation(\n",
    "    job_id=job.job_id,\n",
    ")\n",
    "\n",
    "print(analytical_estimation)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "33e4cad6",
   "metadata": {},
   "source": [
    "## Start Empirical Resource Estimation\n",
    "\n",
    "After the analytical result is available, start the empirical estimation stage explicitly. It determines the exact HQC required for the remaining mitigation at the specified precision. Use `wait_for_resource_estimation(...)` to wait until it completes and retrieve the empirical HQC cost and the mitigation results produced during empirical estimation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b0e19ee5",
   "metadata": {},
   "outputs": [],
   "source": [
    "qedma_client.start_resource_estimation(job_id=job.job_id)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4d2dc9fa",
   "metadata": {},
   "outputs": [],
   "source": [
    "empirical_hqc, empirical_estimation_results = qedma_client.wait_for_resource_estimation(\n",
    "    job_id=job.job_id,\n",
    ")\n",
    "\n",
    "print(empirical_hqc)\n",
    "print(empirical_estimation_results)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2d747b4a",
   "metadata": {},
   "source": [
    "## Start the Full QESEM Run\n",
    "\n",
    "Once the remaining mitigation HQC looks acceptable, start the full job with an explicit `max_hqc` budget. Here, we use `empirical_hqc` because it is the HQC cost needed to achieve the requested precision."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b5c7870c",
   "metadata": {},
   "outputs": [],
   "source": [
    "max_hqc = empirical_hqc\n",
    "\n",
    "qedma_client.start_job(\n",
    "    job_id=job.job_id,\n",
    "    max_hqc=empirical_hqc\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "63641a9c",
   "metadata": {},
   "source": [
    "## Wait for Completion\n",
    "\n",
    "The final wait step returns the job payload, including the mitigated and unmitigated results for each observable and the total HQC consumed."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f5b76bb2",
   "metadata": {},
   "outputs": [],
   "source": [
    "job = qedma_client.wait_for_job_complete(job_id=job.job_id)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9a7f8c7f",
   "metadata": {},
   "source": [
    "## Read the Results\n",
    "\n",
    "Retrieve the completed job with its results. For each observable, the QESEM result format includes both a mitigated and an unmitigated value."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "32779041",
   "metadata": {},
   "outputs": [],
   "source": [
    "job = qedma_client.get_job(job_id=job.job_id, include_results=True)\n",
    "\n",
    "for observable, result in job.results:\n",
    "    print(\"Observable:\", observable)\n",
    "    print(\"Mitigated:\", result.mitigated)\n",
    "    print(\"Unmitigated:\", result.unmitigated)\n",
    "    print()\n",
    "\n",
    "print(\"Total HQC consumed:\", job.hqc)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "96e6cb54",
   "metadata": {},
   "source": [
    "## Summary\n",
    "\n",
    "The Quantinuum QESEM workflow lets you:\n",
    "\n",
    "1. create a job\n",
    "2. determine the exact HQC cost of empirical estimation\n",
    "3. determine the exact time required for the remaining mitigation and inspect intermediate results\n",
    "4. launch the final run with an explicit budget\n",
    "5. retrieve mitigated and unmitigated outputs together with total HQC usage\n",
    "\n",
    "For more detail on the returned fields, continue to [Execution Metrics](/quantinuum/execution_metrics/) and [Reference](../../reference/)."
   ]
  }
 ],
 "metadata": {
  "description": "Run QESEM workflows on Quantinuum systems with staged HQC estimation and explicit execution budgeting.",
  "kernelspec": {
   "display_name": "Python (qedma-docs)",
   "language": "python",
   "name": "qedma-docs"
  },
  "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.13.5"
  },
  "title": "Quantinuum QESEM Quick Start"
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
