{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Examples of tables and plots available from a `Workspace`\n", "\n", "PyGSTi's `Workspace` object is first a foremost a container and factory for plots and tables. At the most basic level, it can be used to generate nice output based on quantities (e.g. `Model`, `DataSet`, etc. objects) that you've computed or loaded within a notebook. For this, it's useful to call `init_notebook_mode` with `autodisplay=True` (see below) so that you don't have to `.display()` everything - `display()` gets called automatically when a plot or table is created.\n", "\n", "## Getting some results\n", "First, let's run Gate Set Tomography (GST) on the standard 1-qubit model to get some results to play with. We generate a few `DataSet` objects and then call `run_long_sequence_gst` to run GST, generating a `ModelEstimateResults` object (essentially a container for `Model` objects). For more details, see the tutorials [GST overview tutorial](../algorithms/GST-Overview.ipynb), the [tutorial on GST functions](../algorithms/GST-Driverfunctions.ipynb), and the [tutorial explaining the ModelEstimateResults object](../objects/advanced/Results.ipynb). " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pygsti\n", "from pygsti.modelpacks import smq1Q_XYI" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#The usual GST setup: we're going to run GST on the standard XYI 1-qubit model\n", "target_model = smq1Q_XYI.target_model()\n", "prep_fiducials = smq1Q_XYI.prep_fiducials()\n", "meas_fiducials = smq1Q_XYI.meas_fiducials()\n", "germs = smq1Q_XYI.germs()\n", "maxLengths = [1,2]\n", "listOfExperiments = pygsti.construction.create_lsgst_circuits(\n", " target_model.operations.keys(), prep_fiducials, meas_fiducials, germs, maxLengths)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Create some datasets for analysis\n", "mdl_datagen1 = target_model.depolarize(op_noise=0.1, spam_noise=0.02)\n", "mdl_datagen2 = target_model.depolarize(op_noise=0.05, spam_noise=0.01).rotate(rotate=(0.01,0.01,0.01))\n", "\n", "ds1 = pygsti.construction.simulate_data(mdl_datagen1, listOfExperiments, n_samples=1000,\n", " sample_error=\"binomial\", seed=1234)\n", "ds2 = pygsti.construction.simulate_data(mdl_datagen2, listOfExperiments, n_samples=1000,\n", " sample_error=\"binomial\", seed=1234)\n", "ds3 = ds1.copy_nonstatic(); ds3.add_counts_from_dataset(ds2); ds3.done_adding_data()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Run GST on all three datasets\n", "target_model.set_all_parameterizations(\"TP\")\n", "results1 = pygsti.run_long_sequence_gst(ds1, target_model, prep_fiducials, meas_fiducials, germs, maxLengths, verbosity=0)\n", "results2 = pygsti.run_long_sequence_gst(ds2, target_model, prep_fiducials, meas_fiducials, germs, maxLengths, verbosity=0)\n", "results3 = pygsti.run_long_sequence_gst(ds3, target_model, prep_fiducials, meas_fiducials, germs, maxLengths, verbosity=0)\n", "\n", "#make some shorthand variable names for later\n", "tgt = results1.estimates['GateSetTomography'].models['target']\n", "\n", "ds1 = results1.dataset\n", "ds2 = results2.dataset\n", "ds3 = results3.dataset\n", "\n", "mdl1 = results1.estimates['GateSetTomography'].models['go0']\n", "mdl2 = results2.estimates['GateSetTomography'].models['go0']\n", "mdl3 = results3.estimates['GateSetTomography'].models['go0']\n", "\n", "gss = results1.circuit_lists['final']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Gallery of `Workspace` plots and tables.\n", "Now that we have some results, let's create a `Workspace` and make some plots and tables.\n", "\n", "To get tables and plots to display properly, one must run `init_notebook_mode`. The `connected` argument indicates whether you want to rely on an active internet connection. If `True`, then resources will be loaded from the web (e.g. a CDN), and if you save a notebook as HTML the file size may be smaller. If `False`, then all the needed resources (except MathJax) are provided by pyGSTi, and an `offline` directory is automatically created in the same directory as your notebook. This directory contains all the necessary resources, and must \"tag along\" with the notebook and any saved-as-HTML versions of it in order for everything to work. The second argument, `autodisplay`, determines whether tables and plots are automatically displayed when they are created. If `autodisplay=False`, one must call the `display()` member function of a table or plot to display it. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "from pygsti.report import workspace\n", "w = workspace.Workspace()\n", "w.init_notebook_mode(connected=False, autodisplay=True) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Plots and tables are created via member functions of a `Workspace` (`w` in our case). Note that you can start typing \"`w.`\" and TAB-complete to see the different things a `Workspace` can make for you. Furthermore, pressing SHIFT-TAB after the opening parenthesis of a function, e.g. after typing \"`w.GatesVsTargetTable(`\", will bring up Jupyter's help window showing you the function signature (the arguments you need to give the function).\n", "\n", "#### The remainder of this tutorial demonstrates some of the tables and plots you can create. \n", "Note that displayed objects have a resize handle in their lower right corner." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "w.ColorBoxPlot((\"logl\",), gss, ds1, mdl1, typ='scatter')\n", "w.ColorBoxPlot((\"logl\",), gss, ds1, mdl1, typ='boxes')\n", "w.ColorBoxPlot((\"logl\",), gss, ds1, mdl1, typ='histogram')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "w.FitComparisonBarPlot(gss, results1.circuit_lists['iteration'],\n", " results1.estimates['GateSetTomography'].models['iteration estimates'], ds1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "w.GramMatrixBarPlot(ds1,tgt)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "w.GatesVsTargetTable(mdl1, tgt)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "w.SpamVsTargetTable(mdl2, tgt)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "w.ColorBoxPlot((\"chi2\",\"logl\"), gss, ds1, mdl1, box_labels=True)\n", " #Notice how long it takes to switch between \"chi2\" and \"logl\". This \n", " # is due to drawing all of the box labels (box_labels=True)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#This one requires knowng that each Results object holds a list of models\n", "# from each GST intation along with the corresponding operation sequences that were used.\n", "w.FitComparisonTable(gss, results1.circuit_lists['iteration'],\n", " results1.estimates['GateSetTomography'].models['iteration estimates'], ds1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# We can reuse 'gss' for all three since the operation sequences are the same.\n", "w.FitComparisonTable([\"GS1\",\"GS2\",\"GS3\"], [gss, gss, gss], [mdl1,mdl2,mdl3], ds1, x_label=\"Model\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "w.ChoiTable(mdl3, display=('matrix','barplot'))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "w.GateMatrixPlot(mdl1[('Gxpi2',0)],scale=1.0, box_labels=True,ylabel=\"hello\")\n", "w.GateMatrixPlot(pygsti.tools.error_generator(mdl1[('Gxpi2',0)], tgt[('Gxpi2',0)], 'pp'), scale=1.5)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from pygsti.modelpacks import smq2Q_XYCNOT\n", "w.GateMatrixPlot(smq2Q_XYCNOT.target_model()[('Gxpi2',0)],scale=1.0, box_labels=False,ylabel=\"hello\",mx_basis=\"pp\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "mx = np.array( \n", "[[ 7.3380823, 8.28446943, 7.4593754, 3.91256384, 0.68631199],\n", " [ 3.36139818, 7.42955114, 6.78516082, 0.35863173, 5.57713093],\n", " [ 2.61489939, 3.40182958, 6.77389064, 9.29736475, 0.33824271],\n", " [ 9.64258149, 9.45928809, 6.91516602, 5.61423854, 0.56480777],\n", " [ 2.15195669, 9.37588783, 5.1781991, 7.20087591, 1.46096288]], 'd')\n", "cMap = pygsti.report.colormaps.LinlogColormap(vmin=0, vmax=10, n_boxes=25, pcntle=0.55, dof_per_box=1, color='blue')\n", "w.MatrixPlot(mx, colormap=cMap, colorbar=False)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "mx = np.identity(3,'d')\n", "mx[0,1] = 2.1\n", "mx[2,2] = 4.0\n", "mx[2,0] = 3.0\n", "mx[0,2] = 7.0\n", "mx[2,1] = 10.0\n", "mx[0,0] = np.nan\n", "cMap = pygsti.report.colormaps.PiecewiseLinearColormap(\n", " [[0,(0,0.5,0)],[1,(0,1.0,0)],[2,(1.0,1.0,0)],\n", " [4,(1.0,0.5,0)],[10,(1.0,0,0)]])\n", "#print(cMap.colorscale())\n", "w.MatrixPlot(mx, colormap=cMap, colorbar=False, grid=\"white:1\", box_labels=True, prec=2,\n", " xlabels=('TP',\"CPTP\",\"full\"),ylabels=(\"DS0\",\"DS1\",\"DS2\"))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "w.ErrgenTable(mdl3,tgt)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "w.PolarEigenvaluePlot([np.linalg.eigvals(mdl2[('Gxpi2',0)])],[\"purple\"],scale=1.5)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "w.GateEigenvalueTable(mdl2, display=('evals','polar'))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "w.GateDecompTable(mdl1,target_model)\n", "#w.old_GateDecompTable(gs1) #historical; 1Q only" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": false }, "outputs": [], "source": [ "#Note 2Q angle decompositions\n", "from pygsti.modelpacks import smq2Q_XXYYII\n", "from pygsti.modelpacks import smq2Q_XYCNOT\n", "\n", "w.GateDecompTable(smq2Q_XXYYII.target_model(), smq2Q_XXYYII.target_model())\n", "\n", "import scipy\n", "I = np.array([[1,0],[0,1]],'complex')\n", "X = np.array([[0,1],[1,0]],'complex')\n", "Y = np.array([[0,1j],[-1j,0]],'complex')\n", "XX = np.kron(X,X)\n", "YY = np.kron(Y,Y)\n", "IX = np.kron(I,X)\n", "XI = np.kron(X,I)\n", "testU = scipy.linalg.expm(-1j*np.pi/2*XX)\n", "testS = pygsti.unitary_to_process_mx(testU)\n", "testS = pygsti.change_basis(testS,\"std\",\"pp\")\n", "\n", "#mdl_decomp = std2Q_XYCNOT.target_model()\n", "#mdl_decomp.operations['Gtest'] = testS\n", "#w.GateDecompTable(mdl_decomp, mdl_decomp)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "dsLabels = [\"A\",\"B\",\"C\"]\n", "datasets = [ds1, ds2, ds3]\n", "dscmps = {}\n", "for i,ds_a in enumerate(datasets):\n", " for j,ds_b in enumerate(datasets[i+1:],start=i+1):\n", " dscmps[(i,j)] = pygsti.objects.DataComparator([ds_a, ds_b])\n", "\n", "w.DatasetComparisonSummaryPlot(dsLabels, dscmps)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "w.DatasetComparisonHistogramPlot(dscmps[(1,2)])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Saving figures to file\n", "You can also save plot and figures to separate files using their `saveas` method. The output format is determined by the file extension, and allowed extensions are:\n", "\n", "- 'pdf': Adobe portable document format\n", "- 'tex': LaTeX source (uncompiled, *tables only*)\n", "- 'pkl': Python pickle (of a pandas `DataFrame` for tables, a dict for plots)\n", "- 'html': A stand-alone HTML document" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import os\n", "if not os.path.exists(\"../tutorial_files/tempTest\"):\n", " os.mkdir(\"../tutorial_files/tempTest\")\n", "\n", "obj = w.GatesVsTargetTable(mdl1, tgt)\n", "#obj = w.ErrgenTable(mdl3,tgt)\n", "#obj = w.ColorBoxPlot((\"logl\",), gss, ds1, mdl1, typ='boxes')\n", "\n", "obj.saveas(\"../tutorial_files/tempTest/testSave.pdf\")\n", "obj.saveas(\"../tutorial_files/tempTest/testSave.tex\")\n", "obj.saveas(\"../tutorial_files/tempTest/testSave.pkl\")\n", "obj.saveas(\"../tutorial_files/tempTest/testSave.html\")" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "## Exporting notebooks to HTML\n", "If you want, you can save figure-containing notebooks (like this one) as an HTML file by going to **File => Download As => HTML** in the Jupyter menu. The resulting file will retain all of the plot interactivity, so long as its in a directory with an `offline` folder (because we set `connected=False` above)." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.7.5" } }, "nbformat": 4, "nbformat_minor": 2 }