{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "9fe051cd",
   "metadata": {},
   "source": [
    "# Run OpenQASM Benzene simulation\n",
    "\n",
    "This sample shows using the QDK tools for visualizing a simulating an OpenQASM program for the Benzene molecule.\n",
    "\n",
    "First, we import the relevant tools and read the OpenQASM source from a file. We can use the QDK to compile this into a QIR program."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ad093c2b",
   "metadata": {},
   "outputs": [],
   "source": [
    "from qdk import init, TargetProfile\n",
    "from qdk.openqasm import circuit, compile, run\n",
    "from qdk.widgets import Circuit, Histogram\n",
    "\n",
    "from pathlib import Path\n",
    "src = Path(\"benzene_diradical_injected_rotation_measurement_circuit_0.qasm\").read_text(encoding=\"utf-8\")\n",
    "\n",
    "init(target_profile=TargetProfile.Base)\n",
    "qir = compile(src)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e97d2017",
   "metadata": {},
   "source": [
    "Next, we can visualize the program as a circuit using the `Circuit` widget."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "eba22bee",
   "metadata": {},
   "outputs": [],
   "source": [
    "Circuit(circuit(src))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "993b5e29",
   "metadata": {},
   "source": [
    "Using the sparse-state simulator, we can run the program without noise and confirm the results visually with the `Histogram` widget."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b4d0339e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Run using the default sparse simulator\n",
    "sim_results = run(src, shots=1024)\n",
    "Histogram(sim_results, labels=\"kets\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fc8bf1e9",
   "metadata": {},
   "source": [
    "Let's see how this program might run when compiled and scheduled for a neutral atom device. We create a new instance of the `NeutralAtomDevice` class with default parameters and trace the QIR program to see what it looks like when compiled to the native gates and movements of such a device."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9737fbd1",
   "metadata": {},
   "outputs": [],
   "source": [
    "from qdk.simulation import NeutralAtomDevice, NoiseConfig\n",
    "\n",
    "device = NeutralAtomDevice()\n",
    "device.show_trace(qir)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c19a823d",
   "metadata": {},
   "source": [
    "Next, we create a noise configuration for the native gates of this neutral atom device, including some probability of qubit loss on movement, and simulate the program targetted for the device using the GPU full-state simulator. You can try varying the noise levels to observe how the results change in the presence of different noise or loss probabilities."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8891c9cd",
   "metadata": {},
   "outputs": [],
   "source": [
    "noise = NoiseConfig()\n",
    "noise.cz.set_depolarizing(0.05)\n",
    "noise.sx.set_bitflip(0.01)\n",
    "noise.mov.loss = 0.001\n",
    "results = device.simulate(qir, shots=1000, noise=noise, type=\"gpu\")\n",
    "Histogram(results, labels=\"kets\", items=\"top-25\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "be4efd09",
   "metadata": {},
   "source": [
    "Additionally, you can use the `MoleculeViewer` widget to visualize the structure of the Benzene molecule we've been experimenting with."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "446d333b",
   "metadata": {},
   "outputs": [],
   "source": [
    "from pathlib import Path\n",
    "from qdk.widgets import MoleculeViewer\n",
    "\n",
    "# Load cached molecule data from file.\n",
    "molecule_data = Path(\"benzene_diradical.structure.xyz\").read_text(encoding=\"utf-8\")\n",
    "\n",
    "# Note: The \"info\" field is optional and can contain any metadata you want to display with the cube data.\n",
    "cube_data = {\n",
    "    \"alpha_18\": {\n",
    "        \"data\": Path(\"MO_alpha_18.cube\").read_text(encoding=\"utf-8\"),\n",
    "        \"info\": {\"Energy (Ha)\": -0.392, \"Symmetry\": \"A1\", \"Occupation\": 1.0}\n",
    "    },\n",
    "    \"alpha_19\": {\n",
    "        \"data\": Path(\"MO_alpha_19.cube\").read_text(encoding=\"utf-8\"),\n",
    "        \"info\": {\"Energy (Ha)\":  0.581, \"Symmetry\": \"B2\", \"Occupation\": 0.0}\n",
    "    }\n",
    "}\n",
    "\n",
    "MoleculeViewer(molecule_data=molecule_data, cube_data=cube_data, isoval=0.03)"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
