{
 "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
}