{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Device backend noise model simulations\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Introduction\n",
    "\n",
    "This notebook shows how to use the Qiskit Aer `noise` module to automatically generate a basic noise model for an IBMQ hardware device, and use this model to do noisy simulations of `QuantumCircuits` to study the effects of errors which occur on real devices.\n",
    "\n",
    "Note, that these automatic models are only an *approximation* of the real errors that occur on actual devices, due to the fact that they must be build from a limited set of input parameters related to *average error rates* on gates. The study of quantum errors on real devices is an active area of research and we discuss the Qiskit Aer tools for configuring more detailed noise models in another notebook."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-19T16:57:28.062507Z",
     "start_time": "2019-08-19T16:57:24.202560Z"
    }
   },
   "outputs": [],
   "source": [
    "from qiskit import QuantumCircuit, transpile\n",
    "from qiskit_aer import AerSimulator\n",
    "from qiskit.visualization import plot_histogram"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Device Backend Noise Model\n",
    "\n",
    "The *Qiskit Aer* device noise model automatically generates a simplified noise model for a real device. This model is generated using the calibration information reported in the `BackendProperties` of a device and takes into account\n",
    "\n",
    "* The *gate_error* probability of each basis gate on each qubit.\n",
    "* The *gate_length* of each basis gate on each qubit.\n",
    "* The $T_1$, $T_2$ relaxation time constants of each qubit.\n",
    "* The readout error probability of each qubit.\n",
    "\n",
    "### Fake Provider Backends\n",
    "\n",
    "We will use real noise data for an IBM Quantum device using the data stored in Qiskit Terra. Specifically, in this tutorial, the device is `ibmq_vigo`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-19T16:57:32.162207Z",
     "start_time": "2019-08-19T16:57:32.159466Z"
    }
   },
   "outputs": [],
   "source": [
    "from qiskit_ibm_runtime.fake_provider import FakeVigo\n",
    "device_backend = FakeVigo()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Test circuit for device and simulation comparison\n",
    "\n",
    "Now we construct a test circuit to compare the output of the real device with the noisy output simulated on the Qiskit Aer `AerSimulator`. We will prepare a 3-qubit GHZ state $\\frac{1}{\\sqrt2}(|0,0,0\\rangle + |1,1,1\\rangle)$ on qubits 0, 1 and 2. Before running with noise or on the device we show the ideal expected output with no noise."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-19T16:57:32.330124Z",
     "start_time": "2019-08-19T16:57:32.175615Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 14940 characters]",
      "text/plain": [
       "<Figure size 504x360 with 1 Axes>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Construct quantum circuit\n",
    "circ = QuantumCircuit(3, 3)\n",
    "circ.h(0)\n",
    "circ.cx(0, 1)\n",
    "circ.cx(1, 2)\n",
    "circ.measure([0, 1, 2], [0, 1, 2])\n",
    "\n",
    "sim_ideal = AerSimulator()\n",
    "\n",
    "# Execute and get counts\n",
    "result = sim_ideal.run(transpile(circ, sim_ideal)).result()\n",
    "counts = result.get_counts(0)\n",
    "plot_histogram(counts, title='Ideal counts for 3-qubit GHZ state')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Generating a simulator that mimics a device\n",
    "\n",
    "We call `from_backend` to create a simulator for `ibmq_vigo`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "sim_vigo = AerSimulator.from_backend(device_backend)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "By storing the device properties in `vigo_simulator`, we ensure that the appropriate basis gates and coupling map are used when compiling circuits for simulation, thereby most closely mimicking the gates that will be executed on a real device. In addition `vigo_simulator` contains an approximate noise model consisting of:\n",
    "\n",
    "* **Single-qubit gate errors** consisting of a single qubit depolarizing error followed by a single qubit thermal relaxation error.\n",
    "* **Two-qubit gate errors** consisting of a two-qubit depolarizing error followed by single-qubit thermal relaxation errors on both qubits in the gate.\n",
    "* **Single-qubit readout errors** on the classical bit value obtained from measurements on individual qubits.\n",
    "\n",
    "For the gate errors the error parameter of the thermal relaxation errors is derived using the `thermal_relaxation_error` function from `aer.noise.errors` module, along with the individual qubit $T_1$ and $T_2$ parameters, and the `gate_time` parameter from the device backend properties. The probability of the depolarizing error is then set so that the combined average gate infidelity from the depolarizing error followed by the thermal relaxation is equal to the `gate_error` value from the backend properties.\n",
    "\n",
    "For the readout errors the probability that the recorded classical bit value will be flipped from the true outcome after a measurement is given by the qubit `readout_errors`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Running a noise simulation\n",
    "\n",
    "Once we have created a noisy simulator backend based on a real device we can use it to run noisy simulations.\n",
    "\n",
    "**Important:** When running noisy simulations it is *critical* to `transpile` the circuit for the backend so that the circuit is transpiled to the correct noisy basis gate set for the backend."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-19T16:57:36.864987Z",
     "start_time": "2019-08-19T16:57:36.672055Z"
    },
    "tags": [
     "nbsphinx-thumbnail"
    ]
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 20388 characters]",
      "text/plain": [
       "<Figure size 504x360 with 1 Axes>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Transpile the circuit for the noisy basis gates\n",
    "tcirc = transpile(circ, sim_vigo)\n",
    "\n",
    "# Execute noisy simulation and get counts\n",
    "result_noise = sim_vigo.run(tcirc).result()\n",
    "counts_noise = result_noise.get_counts(0)\n",
    "plot_histogram(counts_noise,\n",
    "               title=\"Counts for 3-qubit GHZ state with device noise model\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If transpilation is skipped noise from the device noise model will not be applied to gates in the circuit that are supported by the simulator, but not supported by the mimicked backend."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<h3>Version Information</h3><table><tr><th>Qiskit Software</th><th>Version</th></tr><tr><td><code>qiskit</code></td><td>0.22.0.dev0+397a639</td></tr><tr><td><code>qiskit-aer</code></td><td>0.10.4</td></tr><tr><th>System information</th></tr><tr><td>Python version</td><td>3.10.4</td></tr><tr><td>Python compiler</td><td>Clang 12.0.0 </td></tr><tr><td>Python build</td><td>main, Mar 31 2022 03:38:35</td></tr><tr><td>OS</td><td>Darwin</td></tr><tr><td>CPUs</td><td>2</td></tr><tr><td>Memory (Gb)</td><td>8.0</td></tr><tr><td colspan='2'>Thu Jul 14 10:20:15 2022 +08</td></tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div style='width: 100%; background-color:#d5d9e0;padding-left: 10px; padding-bottom: 10px; padding-right: 10px; padding-top: 5px'><h3>This code is a part of Qiskit</h3><p>&copy; Copyright IBM 2017, 2022.</p><p>This code is licensed under the Apache License, Version 2.0. You may<br>obtain a copy of this license in the LICENSE.txt file in the root directory<br> of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.<p>Any modifications or derivative works of this code must retain this<br>copyright notice, and modified files need to carry a notice indicating<br>that they have been altered from the originals.</p></div>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import qiskit\n",
    "qiskit.__version__\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "celltoolbar": "Tags",
  "kernelspec": {
   "display_name": "Python 3.10.4 ('fixissueenv')",
   "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.4"
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  },
  "vscode": {
   "interpreter": {
    "hash": "f53bee1cc8ff042b6860c611f7dc293c44dcfc3f45ad90e95286e8cf5f1fb6ad"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
