{ "cells": [ { "cell_type": "markdown", "id": "0", "metadata": { "papermill": { "duration": 0.009025, "end_time": "2025-02-27T06:29:35.145947", "exception": false, "start_time": "2025-02-27T06:29:35.136922", "status": "completed" }, "tags": [] }, "source": [ "# Circuit from YAML\n", "> Sometimes it's useful to be able to define circuits from YAML definitions. To not re-invent the wheel, SAX uses [GDSFactory](https://gdsfactory.readthedocs.io/en/latest/yaml.html)'s YAML netlist spec to define its circuits. This makes it very easy to convert a GDSFactory layout to a SAX circuit model!" ] }, { "cell_type": "code", "execution_count": null, "id": "1", "metadata": { "papermill": { "duration": 2.548398, "end_time": "2025-02-27T06:29:37.704310", "exception": false, "start_time": "2025-02-27T06:29:35.155912", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "import jax.numpy as jnp\n", "import matplotlib.pyplot as plt\n", "import sax\n", "import yaml" ] }, { "cell_type": "markdown", "id": "2", "metadata": { "papermill": { "duration": 0.003547, "end_time": "2025-02-27T06:29:37.712200", "exception": false, "start_time": "2025-02-27T06:29:37.708653", "status": "completed" }, "tags": [] }, "source": [ "## MZI" ] }, { "cell_type": "markdown", "id": "3", "metadata": { "papermill": { "duration": 0.003594, "end_time": "2025-02-27T06:29:37.719333", "exception": false, "start_time": "2025-02-27T06:29:37.715739", "status": "completed" }, "tags": [] }, "source": [ "Let's first see how we can define a SAX circuit from YAML:" ] }, { "cell_type": "code", "execution_count": null, "id": "4", "metadata": { "papermill": { "duration": 0.01295, "end_time": "2025-02-27T06:29:37.735830", "exception": false, "start_time": "2025-02-27T06:29:37.722880", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "netlist = \"\"\"\n", "instances:\n", " lft:\n", " component: coupler\n", " settings:\n", " coupling: 0.5\n", " rgt:\n", " component: coupler\n", " settings:\n", " coupling: 0.5\n", " top:\n", " component: straight\n", " settings:\n", " length: 25.0\n", " btm:\n", " component: straight\n", " settings:\n", " length: 15.0\n", "\n", "connections:\n", " lft,out0: btm,in0\n", " btm,out0: rgt,in0\n", " lft,out1: top,in0\n", " top,out0: rgt,in1\n", "\n", "ports:\n", " in0: lft,in0\n", " in1: lft,in1\n", " out0: rgt,out0\n", " out1: rgt,out1\n", "\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": null, "id": "5", "metadata": { "papermill": { "duration": 0.023285, "end_time": "2025-02-27T06:29:37.762967", "exception": false, "start_time": "2025-02-27T06:29:37.739682", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "yaml.safe_load(netlist)" ] }, { "cell_type": "code", "execution_count": null, "id": "6", "metadata": { "papermill": { "duration": 1.421887, "end_time": "2025-02-27T06:29:39.188959", "exception": false, "start_time": "2025-02-27T06:29:37.767072", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "mzi, _ = sax.circuit(\n", " yaml.safe_load(netlist),\n", " models={\"coupler\": sax.models.coupler, \"straight\": sax.models.straight},\n", ")" ] }, { "cell_type": "code", "execution_count": null, "id": "7", "metadata": { "papermill": { "duration": 1.34874, "end_time": "2025-02-27T06:29:40.542255", "exception": false, "start_time": "2025-02-27T06:29:39.193515", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "wl = jnp.linspace(1.5, 1.6, 1000)\n", "transmission = jnp.abs(mzi(wl=wl)[\"in0\", \"out0\"]) ** 2\n", "\n", "plt.plot(wl * 1e3, transmission)\n", "plt.xlabel(\"λ [nm]\")\n", "plt.ylabel(\"T\")\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "8", "metadata": { "papermill": { "duration": 0.008232, "end_time": "2025-02-27T06:29:40.562047", "exception": false, "start_time": "2025-02-27T06:29:40.553815", "status": "completed" }, "tags": [] }, "source": [ "That was easy! However, during the above YAML conversion, only models available in `sax.models` were used. What if we want to map the YAML component names to custom models? Let's say we want to use a dispersionless waveguide for the above model for example:" ] }, { "cell_type": "code", "execution_count": null, "id": "9", "metadata": { "papermill": { "duration": 0.015512, "end_time": "2025-02-27T06:29:40.585575", "exception": false, "start_time": "2025-02-27T06:29:40.570063", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "def waveguide_without_dispersion(wl=1.55, length=25.0, neff=2.34):\n", " phase = 2 * jnp.pi * neff * length / wl\n", " sdict = sax.reciprocal({(\"in0\", \"out0\"): jnp.exp(1j * phase)})\n", " return sdict" ] }, { "cell_type": "markdown", "id": "10", "metadata": { "papermill": { "duration": 0.004785, "end_time": "2025-02-27T06:29:40.595274", "exception": false, "start_time": "2025-02-27T06:29:40.590489", "status": "completed" }, "tags": [] }, "source": [ "We can regenerate the above circuit again, but this time we specify a models mapping:" ] }, { "cell_type": "code", "execution_count": null, "id": "11", "metadata": { "papermill": { "duration": 0.114223, "end_time": "2025-02-27T06:29:40.714333", "exception": false, "start_time": "2025-02-27T06:29:40.600110", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "mzi, _ = sax.circuit(\n", " yaml.safe_load(netlist),\n", " models={\"straight\": waveguide_without_dispersion, \"coupler\": sax.models.coupler},\n", ")" ] }, { "cell_type": "markdown", "id": "12", "metadata": { "papermill": { "duration": 0.005149, "end_time": "2025-02-27T06:29:40.724809", "exception": false, "start_time": "2025-02-27T06:29:40.719660", "status": "completed" }, "tags": [] }, "source": [ "> The `models=` keyword in `circuit_from_yaml` can be a dictionary **or** an imported python module (like for example `sax.models`). Or a list containing multiple of such dictionary mappings and imported modules." ] }, { "cell_type": "code", "execution_count": null, "id": "13", "metadata": { "papermill": { "duration": 0.335719, "end_time": "2025-02-27T06:29:41.065461", "exception": false, "start_time": "2025-02-27T06:29:40.729742", "status": "completed" }, "tags": [] }, "outputs": [], "source": [ "wl = jnp.linspace(1.5, 1.6, 1000)\n", "transmission = jnp.abs(mzi(wl=wl)[\"in0\", \"out0\"]) ** 2\n", "\n", "plt.plot(wl, transmission)\n", "plt.xlabel(\"Wavelength [nm]\")\n", "plt.ylabel(\"T\")\n", "plt.show()" ] } ], "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.12.6" }, "papermill": { "default_parameters": {}, "duration": 8.543498, "end_time": "2025-02-27T06:29:42.217253", "environment_variables": {}, "exception": null, "input_path": "examples/03_circuit_from_yaml.ipynb", "output_path": "examples/03_circuit_from_yaml.ipynb", "parameters": {}, "start_time": "2025-02-27T06:29:33.673755", "version": "2.6.0" } }, "nbformat": 4, "nbformat_minor": 5 }