{
"cells": [
{
"cell_type": "markdown",
"id": "e99476a6",
"metadata": {},
"source": [
"# 3.4 How do I make my custom QRenderer?\n",
"\n",
"This notebook walks through a complete, working example of a user-defined renderer:\n",
"`QSkeletonRenderer`. By the end you will understand:\n",
"\n",
"1. How Qiskit Metal's renderer architecture works and where to plug in a new one\n",
"2. The three required methods every renderer must implement\n",
"3. How to add renderer-specific columns to the `QGeometry` tables\n",
"4. How to read, filter, and act on `QGeometry` data from inside a renderer\n",
"\n",
"**The skeleton renderer is already written** \u2014 it lives at\n",
"`tutorials/resources/skeleton_renderer.py`. You only need to register it\n",
"in `config.py` (one line, shown below) to make it available in any `QDesign`.\n",
"After that, every cell in this notebook runs without modification.\n",
"\n",
"> This tutorial assumes an editable install (`pip install -e .`) so that\n",
"> changes to `config.py` are picked up immediately without reinstalling."
]
},
{
"cell_type": "markdown",
"id": "41b00108",
"metadata": {},
"source": [
"> \ud83d\udca1 **Using this tutorial without the Qt GUI**\n",
"> \n",
"> This tutorial uses the desktop `MetalGUI`. To follow along on Colab, Binder, JupyterHub, or any environment where Qt isn't available, **replace any `gui.rebuild()` / `gui.screenshot()` call with `qm.view(design)`** \u2014 it renders the design to a matplotlib `Figure` you can display inline or save with `fig.savefig(...)`.\n",
"> \n",
"> See [1.1 Quick start](../1-Overview/1.1-Quick-start.ipynb) for a complete runnable walkthrough and [`docs/headless-usage.rst`](../../docs/headless-usage.rst) for the full reference."
]
},
{
"cell_type": "markdown",
"id": "a305ebd5",
"metadata": {},
"source": [
"Pre-load all the Qiskit Metal libraries that are needed for the rest of this notebook."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "980c33fe",
"metadata": {},
"outputs": [],
"source": [
"import qiskit_metal as metal\n",
"from qiskit_metal import designs, draw\n",
"from qiskit_metal import MetalGUI, Dict, Headings\n",
"\n",
"from qiskit_metal.qlibrary.qubits.transmon_pocket import TransmonPocket\n",
"from qiskit_metal.qlibrary.qubits.transmon_cross import TransmonCross\n",
"\n",
"from qiskit_metal.renderers.renderer_gds.gds_renderer import QGDSRenderer"
]
},
{
"cell_type": "markdown",
"id": "568c7856",
"metadata": {},
"source": [
"## Integrating the user-defined renderer with the rest of Qiskit Metal\n",
"### Architectural insights\n",
"This section will give you the architectural overview of how Qiskit Metal manages renderers, and how you can add your own.\n",
"\n",
"We will refer to your custom renderer as the `skeleton` renderer, since we will not code tool-specific methods/classes, but only worry about how to bootstrap one without functionality.\n",
"\n",
"Note that all renderers (existing `gds`, `hfss` and `q3d` as well as the newly created `skeleton`) have to be identified in the config.py file. Therefore, you will be required to modify the `qiskit_metal/config.py` file.\n",
"\n",
"The following image describes how the QRenderer (superclass of all renderers) interacts with the rest of Qiskit Metal. The key take-away is that creating a QDesign class object initiates all the QRenderer subclass objects as well. Specifically, the `QDesign.__init__()` method reads the `renderers_to_load` dictionary from the config.py file, which enumerates which QRenderers subclasses need to be instantiated. After instantiating the renderer objects, the `QDesign.__init__()` registers them in the `QDesign._renderers` dictionary for later reference."
]
},
{
"attachments": {
"68e1e214-00fe-404e-ad9c-869a18d226f8.jpg": {
"image/jpeg": "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eD9MuNZ1jUNOaO3tLWMyzTPuHyoi5JPsK5fxL8Wvil8B/h78MLaw+E2seOtHbRLa31n+yAsmoadcQ20SqptGwXUneHO4bSuOc0AZv7IXw7/ZH0y71P4i/soa28mmalapa3ml2+pz3NpDJvEglktblnlhuDjBLEHaSNvNfc9fll+zh4D8T+Mv2udZ/aK8PfDG/wDhB4LfRP7OntNRgSwuNYvXfcJmtIiVCqMHf/ERk/NX6m0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf//R/fyiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACkIyCPWlooA+cf2afgRcfALw94v0S51VdWPifxTqviJXSMxiJdRZCISCTkps5PfNfR1FFABRRRQAUUUUAFFFFAHI+LvAPgjx9BaW3jXQrLW47CZLi2+1wJMYJkYMrxlgSjZUcqRnGDxXXUUUAFFFFABRRRQAV8iftA/swat8U/HXh34wfDbxvdfD/x/wCGLWWxt7+GBLqCezmbe0E8L4BUsScjn26V9d0UAfnuf2Pfi18TNe0G9/aY+LcnjHQfDt7FqEWhafp8en2dxdW53RSXDhmdwh524wfav0HVVRQijCqMADsBS0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB//9L9/KKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//T/fyiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA/NX4uftlfE3wH8UPE3gnQ9I0eax0S6SCKS4juGlcNBHKSxSZVzlyOAOBXnn/Devxj/6Amg/9+rr/wCSK8P/AGj/APk4H4gf9hGP/wBJLevGK/ofJuD8tq4SjUnRTbjFvfdr1Py3H59i4V5wjU0T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5h/qZX/nX4n4h5FGRX7ef8Mnfs8/9CZbf9/rj/47R/wyd+zz/wBCZbf9/rj/AOO0f8RUwn/PqX4f5h/qZX/nX4n4h5FGRX7ef8Mnfs8/9CZbf9/rj/47R/wyd+zz/wBCZbf9/rj/AOO0f8RUwn/PqX4f5h/qZX/nX4n4h5FGRX7ef8Mnfs8/9CZbf9/rj/47R/wyd+zz/wBCZbf9/rj/AOO0f8RUwn/PqX4f5h/qZX/nX4n4h5FGRX7ef8Mnfs8/9CZbf9/rj/47R/wyd+zz/wBCZbf9/rj/AOO0f8RUwn/PqX4f5h/qZX/nX4n4h5FGRX7ef8Mnfs8/9CZbf9/rj/47R/wyd+zz/wBCZbf9/rj/AOO0f8RUwn/PqX4f5h/qZX/nX4n4h5FGRX7ef8Mnfs8/9CZbf9/rj/47R/wyd+zz/wBCZbf9/rj/AOO0f8RUwn/PqX4f5h/qZX/nX4n4h5FGRX7ef8Mnfs8/9CZbf9/rj/47R/wyd+zz/wBCZbf9/rj/AOO0f8RUwn/PqX4f5h/qZX/nX4n4h5FGRX7ef8Mnfs8/9CZbf9/rj/47R/wyd+zz/wBCZbf9/rj/AOO0f8RUwn/PqX4f5h/qZX/nX4n4h5FGRX7ef8Mnfs8/9CZbf9/rj/47R/wyd+zz/wBCZbf9/rj/AOO0f8RUwn/PqX4f5h/qZX/nX4n4h5FGRX7ef8Mnfs8/9CZbf9/rj/47R/wyd+zz/wBCZbf9/rj/AOO0f8RUwn/PqX4f5h/qZX/nX4n4h5FGRX7ef8Mnfs8/9CZbf9/rj/47R/wyd+zz/wBCZbf9/rj/AOO0f8RUwn/PqX4f5h/qZX/nX4n4h5FGRX7ef8Mnfs8/9CZbf9/rj/47R/wyd+zz/wBCZbf9/rj/AOO0f8RUwn/PqX4f5h/qZX/nX4n4h5FGRX7ef8Mnfs8/9CZbf9/rj/47R/wyd+zz/wBCZbf9/rj/AOO0f8RUwn/PqX4f5h/qZX/nX4n4h5FGRX7ef8Mnfs8/9CZbf9/rj/47R/wyd+zz/wBCZbf9/rj/AOO0f8RUwn/PqX4f5h/qZX/nX4n4h5FGRX7ef8Mnfs8/9CZbf9/rj/47R/wyd+zz/wBCZbf9/rj/AOO0f8RUwn/PqX4f5h/qZX/nX4n4h5FGRX7ef8Mnfs8/9CZbf9/rj/47R/wyd+zz/wBCZbf9/rj/AOO0f8RUwn/PqX4f5h/qZX/nX4n4h5FGRX7ef8Mnfs8/9CZbf9/rj/47R/wyd+zz/wBCZbf9/rj/AOO0f8RUwn/PqX4f5h/qZX/nX4n4h5FGRX7ef8Mnfs8/9CZbf9/rj/47R/wyd+zz/wBCZbf9/rj/AOO0f8RUwn/PqX4f5h/qZX/nX4n4h5FfpJ/wT1/49/iB/wBdtN/9FzV9Mf8ADJ37PP8A0Jlt/wB/rj/47Xo3gH4U/D74Xx30XgLRo9IXUmja4EbyP5hiBCE+YzdAx6etfP8AFHHmHx+DlhqdOSbtvbo79z1Mm4bq4auqspJpX7noVFFFflh9kFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf/T/fyiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/1P38ooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/9X9/KKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//W/fyiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/2Q=="
}
},
"cell_type": "markdown",
"id": "48c8822c",
"metadata": {},
"source": [
""
]
},
{
"cell_type": "markdown",
"id": "fccdca7b",
"metadata": {},
"source": [
"### QRenderer inheritance and subclass management\n",
"\n",
"Presently, the config.py file references three QRenderers subclasses, which handle the `gds`, `hfss` and `q3d` interfaces. Explicitly, QGDSRenderer is a subclass of QRenderer. Both QHFSSRenderer and QQ3DRenderer subclass from QAnsysRenderer. The class QAnsysRenderer is a subclass of QRenderer.\n",
"\n",
"The `renderers_to_load` dictionary in the config.py file needs to be updated to inform Qiskit Metal about the new renderer `skeleton` you are going to create. `renderers_to_load` stores the explicit path and class name so that Qiskit Metal will load to memory by default only those specified renderers. This happens during the `QDesign.__init__()`.\n",
"\n",
"For this notebook, we created a sample class named QSkeletonRender in `tutorials/resources/skeleton_renderer`. This class is your skeleton to develop a new QRenderer subclass. Feel free to edit the class content at will. If you change the path to the file, please reflect that in the remainder of this notebook. Presently, you can find the production QRenderers subclasses in the package directory `qiskit_metal.renderers`."
]
},
{
"cell_type": "markdown",
"id": "5d38b9d0",
"metadata": {},
"source": [
"### One-time setup: register the skeleton renderer in `config.py`\n",
"\n",
"Open `src/qiskit_metal/config.py` and add the following entry to the\n",
"`renderers_to_load` dict (alongside the existing `gds`, `hfss`, `q3d` entries):\n",
"\n",
"```python\n",
"skeleton=Dict(\n",
" path_name=\"tutorials.resources.skeleton_renderer\",\n",
" class_name=\"QSkeletonRenderer\",\n",
"),\n",
"```\n",
"\n",
"Save the file and **restart the kernel** so the new config is loaded.\n",
"You only need to do this once \u2014 after that `design.renderers.skeleton` will\n",
"be available in any notebook.\n",
"\n",
"> **Why config.py?** Qiskit Metal reads `renderers_to_load` during `QDesign.__init__`\n",
"> to instantiate and register all renderers automatically. Adding your renderer here\n",
"> means users never have to import or instantiate it manually."
]
},
{
"cell_type": "markdown",
"id": "f6ee9a88",
"metadata": {},
"source": [
"### The skeleton renderer source\n",
"\n",
"Open [`tutorials/resources/skeleton_renderer.py`](../resources/skeleton_renderer.py)\n",
"to read the full implementation. The three methods every renderer must provide are\n",
"already implemented there:\n",
"\n",
"```python\n",
"def _initiate_renderer(self):\n",
" \"\"\"Called when the renderer is registered. Return True on success.\"\"\"\n",
" return True\n",
"\n",
"def _close_renderer(self):\n",
" \"\"\"Called on cleanup / disconnect. Return True on success.\"\"\"\n",
" return True\n",
"\n",
"def render_design(self):\n",
" \"\"\"The main export entry point called by the GUI toolbar and scripts.\"\"\"\n",
" self.write_qgeometry_table_names_to_file(\n",
" file_name=self.options.file_geometry_tables,\n",
" highlight_qcomponents=[],\n",
" )\n",
"```\n",
"\n",
"For your own renderer, replace the body of `render_design` with calls to\n",
"your target tool's API (e.g. open a file, call a COM interface, write a mesh)."
]
},
{
"cell_type": "markdown",
"id": "ef964e2a",
"metadata": {},
"source": [
"### Confirm QDesign is able to load your renderer\n",
"Create a QDesign instance."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2e319bad",
"metadata": {},
"outputs": [],
"source": [
"design = designs.DesignPlanar()"
]
},
{
"cell_type": "markdown",
"id": "3180ae21",
"metadata": {},
"source": [
"If you modified the config.py correctly, the previous command should have instantiated and registered the `skeleton` renderer. Verify that by inspecting the renderers dictionary property of the QDesign instance.\n",
"\n",
"If executing the next cell does not show the `skeleton` renderer in the list, please make sure you correctly updated the `config.py` file, next you could try resetting the jupyter notebook kernel, or restarting jupyter notebook."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "da96be81",
"metadata": {},
"outputs": [],
"source": [
"design.renderers.keys()"
]
},
{
"cell_type": "markdown",
"id": "28a04f74",
"metadata": {},
"source": [
"For convenience, let's create a short-handle alias to refer to the renderer during the remainder of this notebook."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0c269b9e",
"metadata": {},
"outputs": [],
"source": [
"a_skeleton = design.renderers.skeleton"
]
},
{
"cell_type": "markdown",
"id": "cde32b77",
"metadata": {},
"source": [
"## Interact with your new user-custom renderer\n",
"\n",
"### Verify and modify the options of your renderer\n",
"\n",
"In the QSkeletonRenderer class some sample `default_options` class parameter has been defined.
\n",
"`default_options = Dict(\n",
" number_of_bones='206')\n",
"`\n",
"\n",
"The instance `a_skeleton` will contain a dictionary `options` that is initiated using the `default_options`. (This works similarly to `options` for QComponents, which has been introduced in the jupyter notebooks found in the folder: `tutorials/2 Front End User`.)\n",
"\n",
"You can access and modify the options in the QSkeletonRenderer class instance as follows. For example, let's update the skeleton from that of a human to that of a dog (319 bones)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "413f2375",
"metadata": {},
"outputs": [],
"source": [
"a_skeleton.options.number_of_bones = \"319\"\n",
"a_skeleton.options"
]
},
{
"cell_type": "markdown",
"id": "e15c5210",
"metadata": {},
"source": [
"Original values will continue being accessible like so:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "dc416882",
"metadata": {},
"outputs": [],
"source": [
"a_skeleton.get_template_options(design)"
]
},
{
"cell_type": "markdown",
"id": "f977c54f",
"metadata": {},
"source": [
"### Populate a sample QDesign to demonstrate interaction with the renderer\n",
"This portion is described in notebooks within directory `tutorials/2 Front End User`. Some of the options have been made distinctly different to show what can be done, i.e., fillet value, fillet='25um', varies for each cpw. However, that may not be what user will implement for their design."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "99e6d92b",
"metadata": {},
"outputs": [],
"source": [
"gui = MetalGUI(design)\n",
"# Headless alternative: import qiskit_metal as qm \u2192 qm.view(design) after build\n",
"design.overwrite_enabled = True\n",
"\n",
"from qiskit_metal.qlibrary.qubits.transmon_pocket import TransmonPocket\n",
"from qiskit_metal.qlibrary.tlines.meandered import RouteMeander"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "244ef5cf",
"metadata": {},
"outputs": [],
"source": [
"## Custom options for all the transmons\n",
"options = dict(\n",
" pad_width=\"425 um\",\n",
" pad_gap=\"80 um\",\n",
" pocket_height=\"650um\",\n",
" # Adding 4 connectors (see below for defaults)\n",
" connection_pads=dict(\n",
" a=dict(loc_W=+1, loc_H=+1),\n",
" b=dict(loc_W=-1, loc_H=+1, pad_height=\"30um\"),\n",
" c=dict(loc_W=+1, loc_H=-1, pad_width=\"200um\"),\n",
" d=dict(loc_W=-1, loc_H=-1, pad_height=\"50um\"),\n",
" ),\n",
")\n",
"\n",
"## Create 4 TransmonPockets\n",
"q1 = TransmonPocket(\n",
" design,\n",
" \"Q1\",\n",
" options=dict(\n",
" pos_x=\"+2.55mm\", pos_y=\"+0.0mm\", gds_cell_name=\"FakeJunction_02\", **options\n",
" ),\n",
")\n",
"q2 = TransmonPocket(\n",
" design,\n",
" \"Q2\",\n",
" options=dict(\n",
" pos_x=\"+0.0mm\",\n",
" pos_y=\"-0.9mm\",\n",
" orientation=\"90\",\n",
" gds_cell_name=\"FakeJunction_02\",\n",
" **options,\n",
" ),\n",
")\n",
"q3 = TransmonPocket(\n",
" design,\n",
" \"Q3\",\n",
" options=dict(\n",
" pos_x=\"-2.55mm\", pos_y=\"+0.0mm\", gds_cell_name=\"FakeJunction_01\", **options\n",
" ),\n",
")\n",
"q4 = TransmonPocket(\n",
" design,\n",
" \"Q4\",\n",
" options=dict(\n",
" pos_x=\"+0.0mm\",\n",
" pos_y=\"+0.9mm\",\n",
" orientation=\"90\",\n",
" gds_cell_name=\"my_other_junction\",\n",
" **options,\n",
" ),\n",
")\n",
"\n",
"options = Dict(meander=Dict(lead_start=\"0.1mm\", lead_end=\"0.1mm\", asymmetry=\"0 um\"))\n",
"\n",
"\n",
"def connect(\n",
" component_name: str,\n",
" component1: str,\n",
" pin1: str,\n",
" component2: str,\n",
" pin2: str,\n",
" length: str,\n",
" asymmetry=\"0 um\",\n",
" flip=False,\n",
" fillet=\"50um\",\n",
"):\n",
" \"\"\"Connect two pins with a CPW.\"\"\"\n",
" myoptions = Dict(\n",
" fillet=fillet,\n",
" pin_inputs=Dict(\n",
" start_pin=Dict(component=component1, pin=pin1),\n",
" end_pin=Dict(component=component2, pin=pin2),\n",
" ),\n",
" lead=Dict(start_straight=\"0.13mm\", end_straight=\"0.13mm\"),\n",
" total_length=length,\n",
" )\n",
" myoptions.update(options)\n",
" myoptions.meander.asymmetry = asymmetry\n",
" myoptions.meander.lead_direction_inverted = \"true\" if flip else \"false\"\n",
" return RouteMeander(design, component_name, myoptions)\n",
"\n",
"\n",
"asym = 90\n",
"cpw1 = connect(\"cpw1\", \"Q1\", \"d\", \"Q2\", \"c\", \"5.7 mm\", f\"+{asym}um\", fillet=\"25um\")\n",
"cpw2 = connect(\n",
" \"cpw2\", \"Q3\", \"c\", \"Q2\", \"a\", \"5.6 mm\", f\"-{asym}um\", flip=True, fillet=\"100um\"\n",
")\n",
"cpw3 = connect(\"cpw3\", \"Q3\", \"a\", \"Q4\", \"b\", \"5.5 mm\", f\"+{asym}um\", fillet=\"75um\")\n",
"cpw4 = connect(\"cpw4\", \"Q1\", \"b\", \"Q4\", \"d\", \"5.8 mm\", f\"-{asym}um\", flip=True)\n",
"\n",
"gui.rebuild()\n",
"gui.autoscale()"
]
},
{
"cell_type": "markdown",
"id": "bd5132ff",
"metadata": {},
"source": [
"### Export list of the design QGeometries to file using your custom QSkeletonRenderer\n",
"The QSkeletonRenderer class contains several sample methods. Let's use one intended to print out the name of the QGeometry tables to a text file (Remember: QGeometry contains the list of the raw layout shapes that compose the design, which we have created in the previous cell)."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ee1f8a87",
"metadata": {},
"outputs": [],
"source": [
"a_skeleton.write_qgeometry_table_names_to_file(\"./simple_output.txt\")"
]
},
{
"cell_type": "markdown",
"id": "4ce36816",
"metadata": {},
"source": [
"Here another example where we sub select a single QComponent instance (`cpw1`) of type RouteMeander. This will only export the name of tables containing shapes related to that instance, which in this case is only paths, and not junctions or poly."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a216d2d3",
"metadata": {},
"outputs": [],
"source": [
"a_skeleton.write_qgeometry_table_names_to_file(\n",
" \"./simple_output_cpw1.txt\", highlight_qcomponents=[\"cpw1\"]\n",
")"
]
},
{
"cell_type": "markdown",
"id": "5bc2afb8",
"metadata": {},
"source": [
"## What if my new tool requires additional parameters that Qiskit Metal does not natively support?"
]
},
{
"cell_type": "markdown",
"id": "8f3b1d99",
"metadata": {},
"source": [
"### QRenderers can request special tool parameters from the user\n",
"\n",
"External tools, such as Ansys, might require special parameters to be able to render (interpret) correctly the QGeometries that Qiskit Metal wants to pass (render) to them. Every tool might need a different set of special parameters; thus we architected a solution that allows individual QRenderers to communicate to qiskit-metal what additional parameters their associated tool requires.\n",
"\n",
"The implementation consists of enabling the QRenderers to add new columns (parameters) and tables (geometry types) to the QGeometry table collection. The QRenderer should also specify what is the default value to use to populate those columns/tables. The user can then update them to a value different than default by editing them at run-time, which can happen through the QComponent options (or directly, for advanced users). Note that older QComponents remain valid also for newer QRenderers, thanks to the defaults provided by the QRenderer.\n",
"\n",
"Our QSkeletonRenderer class for example is designed to add a `a_column_name` column to the `junction` table, with default value `a_default_value`. This is implemented by creating the following class parameter: \n",
"
`element_table_data = dict(junction=dict(a_column_name='a_default_value'))` \n",
"\n",
"Note that the final column name will be `skeleton_a_column_name` because the provided column name is prefixed with the renderer name (`QSkeletonRenderer.name`).\n",
"\n",
"The method that executes the magic described above is `QRenderer.load()`, which is called from the `QSkeletonRenderer.__init__()`."
]
},
{
"cell_type": "markdown",
"id": "bd2ce7f4",
"metadata": {},
"source": [
"### Let's observe and update the additional properties that our QSkeletonRenderer needs\n",
"First, make sure that the registration of the QRenderer added the additional parameter as expected. Search for the column `skeleton_a_column_name` in the qgeometry table `junction`"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0c57bf2c",
"metadata": {},
"outputs": [],
"source": [
"design.qgeometry.tables[\"junction\"]"
]
},
{
"cell_type": "markdown",
"id": "a0781ceb",
"metadata": {},
"source": [
"If you cannot locate the new column (might need to scroll to the far right), then something must be amiss, so please start over this notebook and execute all of the cells.\n",
"\n",
"Once you can locate the new column, and observe the set default value, let's now try to update the value in the column by modifying the design of the correspondent QComponent. All we need to do is pass a different set of options to the component, like so:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2a95c418",
"metadata": {},
"outputs": [],
"source": [
"q1.options.skeleton_a_column_name = \"q1 skeleton\"\n",
"q2.options.skeleton_a_column_name = \"q2 skeleton\"\n",
"q3.options.skeleton_a_column_name = \"q3 skeleton\"\n",
"q4.options.skeleton_a_column_name = \"q4 skeleton\"\n",
"\n",
"gui.rebuild() # Headless: qm.view(design)\n",
"gui.autoscale() # Headless: omit \u2014 autoscale is GUI-only\n",
"\n",
"design.qgeometry.tables[\"junction\"]"
]
},
{
"cell_type": "markdown",
"id": "39c749e2",
"metadata": {},
"source": [
"You can also create the components by directly passing the options you know the renderer will require, like so:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a5012279",
"metadata": {},
"outputs": [],
"source": [
"q1.delete()\n",
"q2.delete()\n",
"q3.delete()\n",
"q4.delete()\n",
"\n",
"q1 = TransmonPocket(\n",
" design,\n",
" \"Q1\",\n",
" options=dict(\n",
" pos_x=\"+2.55mm\",\n",
" pos_y=\"+0.0mm\",\n",
" gds_cell_name=\"FakeJunction_02\",\n",
" skeleton_a_column_name=\"q1 skeleton 2\",\n",
" **options,\n",
" ),\n",
")\n",
"q2 = TransmonPocket(\n",
" design,\n",
" \"Q2\",\n",
" options=dict(\n",
" pos_x=\"+0.0mm\",\n",
" pos_y=\"-0.9mm\",\n",
" orientation=\"90\",\n",
" gds_cell_name=\"FakeJunction_02\",\n",
" skeleton_a_column_name=\"q2 skeleton 2\",\n",
" **options,\n",
" ),\n",
")\n",
"q3 = TransmonPocket(\n",
" design,\n",
" \"Q3\",\n",
" options=dict(\n",
" pos_x=\"-2.55mm\",\n",
" pos_y=\"+0.0mm\",\n",
" gds_cell_name=\"FakeJunction_01\",\n",
" skeleton_a_column_name=\"q3 skeleton 2\",\n",
" **options,\n",
" ),\n",
")\n",
"q4 = TransmonPocket(\n",
" design,\n",
" \"Q4\",\n",
" options=dict(\n",
" pos_x=\"+0.0mm\",\n",
" pos_y=\"+0.9mm\",\n",
" orientation=\"90\",\n",
" gds_cell_name=\"my_other_junction\",\n",
" skeleton_a_column_name=\"q4 skeleton 2\",\n",
" **options,\n",
" ),\n",
")\n",
"\n",
"design.qgeometry.tables[\"junction\"]"
]
},
{
"cell_type": "markdown",
"id": "f975ac81",
"metadata": {},
"source": [
"## Can my user-defined renderer change/interact with the design?\n",
"### Accessing information and methods\n",
"It is possible that the result of a rendering action, or analysis requires a design update back to qiskit-metal. This can be achieved without the user intervention by simply controlling the QDesign instance from within the QRenderer.\n",
"\n",
"Just as an example, the next three cells inspect the current design QComponent, QGeometry table, and QRenderer names."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "dd08fd92",
"metadata": {},
"outputs": [],
"source": [
"a_skeleton.design.components.keys()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c00d7ed3",
"metadata": {},
"outputs": [],
"source": [
"a_skeleton.design.qgeometry.tables.keys()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9c8a932d",
"metadata": {},
"outputs": [],
"source": [
"a_skeleton.design.renderers.keys()"
]
},
{
"cell_type": "markdown",
"id": "4faee4aa",
"metadata": {},
"source": [
"The base QRenderer class comes with useful methods to more easily access some of the information. You will find more method described in the QRenderer documentation. The example below for example returns the QComponent's IDs."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2cd259c3",
"metadata": {},
"outputs": [],
"source": [
"a_skeleton.get_unique_component_ids(\n",
" highlight_qcomponents=[\"Q1\", \"Q1\", \"Q4\", \"cpw1\", \"cpw2\", \"cpw3\", \"cpw4\"]\n",
")"
]
},
{
"cell_type": "markdown",
"id": "2537cbe6",
"metadata": {},
"source": [
"The following instead shows three ways to access the same QGeometry table."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "39330c94",
"metadata": {},
"outputs": [],
"source": [
"a_skeleton.design.components[\"Q1\"].qgeometry_table(\"junction\") # via QComonent name\n",
"a_skeleton.design._components[9].qgeometry_table(\"junction\") # via QComponent ID\n",
"q1.qgeometry_table(\"junction\") # via the QComponent instance"
]
},
{
"cell_type": "markdown",
"id": "24dab83a",
"metadata": {},
"source": [
"The method `QSkeletonRenderer.get_qgeometry_tables_for_skeleton()` exemplifies how to iterate through chips and tables."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9e5ea082",
"metadata": {},
"outputs": [],
"source": [
"from tutorials.resources.skeleton_renderer import QSkeletonRenderer\n",
"\n",
"# The '?' IPython magic displays the docstring for the method inline.\n",
"# Non-IPython equivalent: help(QSkeletonRenderer.get_qgeometry_tables_for_skeleton)\n",
"?QSkeletonRenderer.get_qgeometry_tables_for_skeleton"
]
},
{
"cell_type": "markdown",
"id": "641a6b2a",
"metadata": {},
"source": [
"### Communicate state\n",
"We can also interact with any other method of the QDesign instance, for example we can generate a warning into the logger as shown in the next cell. This is particularly useful to document problems with the user defined QRenderer execution"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a813fb8b",
"metadata": {},
"outputs": [],
"source": [
"# Purposefully generates a warning message.\n",
"a_skeleton.logger.warning(\"Show a warning message for plugin developer.\")"
]
},
{
"cell_type": "markdown",
"id": "bb087230",
"metadata": {},
"source": [
"## Qiskit Metal Version"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "04b46ea8",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"metal.about();"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "dbf6dac5",
"metadata": {},
"outputs": [],
"source": [
"# Uncomment to close the GUI window when done:\n",
"# gui.main_window.close()"
]
}
],
"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.11.14"
}
},
"nbformat": 4,
"nbformat_minor": 5
}