Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Component.plot() takes kwargs to configure the settings for matplotlib #655

Merged
merged 4 commits into from Sep 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,10 @@
# [CHANGELOG](https://keepachangelog.com/en/1.0.0/)

## [5.25.1](https://github.com/gdsfactory/gdsfactory/pull/652)

- Component.plot() takes kwargs to configure the settings


## [5.25.0](https://github.com/gdsfactory/gdsfactory/pull/651)

- rewrite get_netlist() to be more robust and to warn about more issues in optical routing. [PR](https://github.com/gdsfactory/gdsfactory/pull/651)
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Expand Up @@ -22,11 +22,11 @@ major:
python docs/write_components_doc.py

plugins:
pip install -r requirements_sipann.txt
pip install -e .[tidy3d]
pip install jax jaxlib
mamba install pymeep=*=mpi_mpich_* -y
mamba install numpy==1.22 -y
pip install -r requirements_sipann.txt
pip install --upgrade "protobuf<=3.20.1"

meep:
mamba install pymeep=*=mpi_mpich_* -y
Expand Down
207 changes: 207 additions & 0 deletions docs/notebooks/plugins/sax/sax.ipynb
Expand Up @@ -1425,6 +1425,213 @@
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "d51f18ec-0586-4bf2-93ee-22f6656fcd09",
"metadata": {},
"source": [
"## Tuning\n",
"\n",
"You can make a phase shifter model that depends on the applied volage. For that you need first to figure out what's the model associated to your phase shifter, and what is the parameter that you need to tune."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "100d0784-b46f-428b-882a-653b613e33bf",
"metadata": {},
"outputs": [],
"source": [
"import gdsfactory as gf\n",
"import numpy as np\n",
"import sax\n",
"import matplotlib.pyplot as plt\n",
"from tqdm import trange\n",
"import jax.numpy as jnp\n",
"import jax"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d24fc622-6975-4d3d-8011-629bfce42abc",
"metadata": {},
"outputs": [],
"source": [
"delta_length = 10\n",
"mzi_component = gf.components.mzi_phase_shifter_top_heater_metal(delta_length=delta_length)\n",
"mzi_component"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "163f7aae-8a83-4286-bccd-30ed13a1e71d",
"metadata": {},
"outputs": [],
"source": [
"def straight(wl=1.5, length=10.0, neff=2.4) -> sax.SDict:\n",
" wl0 = 1.5 # center wavelength for which the waveguide model is defined\n",
" return sax.reciprocal({(\"o1\", \"o2\"): jnp.exp(2j * jnp.pi * neff * length / wl)})\n",
"\n",
"\n",
"def mmi1x2()->sax.SDict:\n",
" \"\"\"Returns a perfect 1x2 splitter.\"\"\"\n",
" return sax.reciprocal(\n",
" {\n",
" (\"o1\", \"o2\"): 0.5**0.5,\n",
" (\"o1\", \"o3\"): 0.5**0.5,\n",
" }\n",
" )\n",
"\n",
"\n",
"def bend_euler(wl=1.5, length=20.0)->sax.SDict:\n",
" \"\"\"Returns bend Sparameters with reduced transmission compared to a straight.\"\"\"\n",
" return {k: 0.99 * v for k, v in straight(wl=wl, length=length).items()}\n",
"\n",
"\n",
"def phase_shifter_heater(\n",
" wl: float = 1.55,\n",
" neff: float = 2.34,\n",
" voltage: float = 0,\n",
" length: float = 10,\n",
" loss: float = 0.0\n",
") -> sax.SDict:\n",
" \"\"\"Returns simple phase shifter model\"\"\"\n",
" deltaphi = voltage * jnp.pi\n",
" phase = 2 * jnp.pi * neff * length / wl + deltaphi\n",
" amplitude = jnp.asarray(10 ** (-loss * length / 20), dtype=complex)\n",
" transmission = amplitude * jnp.exp(1j * phase)\n",
" sdict = sax.reciprocal(\n",
" {\n",
" (\"o1\", \"o2\"): transmission,\n",
" }\n",
" )\n",
" return sdict\n",
"\n",
"\n",
"models={\n",
" \"bend_euler\": bend_euler,\n",
" \"mmi1x2\": mmi1x2,\n",
" \"straight\": straight,\n",
" \"straight_heater_metal_undercut\": phase_shifter_heater\n",
" }"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9030fb6e-3ac6-4756-96c3-cc202b467cc4",
"metadata": {},
"outputs": [],
"source": [
"mzi_component = gf.components.mzi_phase_shifter_top_heater_metal(delta_length=delta_length)\n",
"netlist=mzi_component.get_netlist()\n",
"mzi_circuit, _ = sax.circuit(\n",
" netlist=netlist,\n",
" models=models\n",
")\n",
"S = mzi_circuit(wl=1.55)\n",
"S"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e53ed40b-1b07-4c41-92ae-e6ae5ed49836",
"metadata": {},
"outputs": [],
"source": [
"wl = np.linspace(1.5, 1.6, 256)\n",
"S = mzi_circuit(wl=wl)\n",
"\n",
"plt.figure(figsize=(14, 4))\n",
"plt.title(\"MZI\")\n",
"plt.plot(1e3 * wl, jnp.abs(S[\"o1\", \"o2\"]) ** 2)\n",
"plt.xlabel(\"λ [nm]\")\n",
"plt.ylabel(\"T\")\n",
"plt.grid(True)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "92cbb478-1c68-4cf0-b693-f873a74d79c8",
"metadata": {},
"source": [
"Now you can tune the phase shift applied to one of the arms.\n",
"\n",
"How do you find out what's the name of the netlist component that you want to tune?\n",
"\n",
"You can backannotate the netlist and read the labels on the backannotated netlist or you can plot the netlist"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cd0e9f81-b19a-469d-8712-8c334006e24f",
"metadata": {},
"outputs": [],
"source": [
"mzi_component.plot_netlist()"
]
},
{
"cell_type": "markdown",
"id": "9a9c888c-0523-4985-ad84-26dbf4fa7891",
"metadata": {},
"source": [
"As you can see the top phase shifter instance `sxt` is hard to see on the netlist.\n",
"You can also reconstruct the component using the netlist and look at the labels in klayout."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4bc0d061-7ec4-4dad-bd22-f841ce7ff7a5",
"metadata": {},
"outputs": [],
"source": [
"mzi_yaml = mzi_component.get_netlist_yaml()\n",
"mzi_component2 = gf.read.from_yaml(mzi_yaml)\n",
"fig = mzi_component2.plot(label_aliases=True)"
]
},
{
"cell_type": "markdown",
"id": "da63cd80-761d-4962-ba16-0a6f8e39d10e",
"metadata": {},
"source": [
"Or in klayout\n",
"\n",
"![](https://i.imgur.com/mBw3gYI.png)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8c687b43-a361-48c5-adc8-ac4d05f72e53",
"metadata": {},
"outputs": [],
"source": [
"voltages = np.linspace(-1, 1, num=5)\n",
"voltages = [-0.5, 0, 0.5]\n",
"\n",
"for voltage in voltages:\n",
" S = mzi_circuit(\n",
" wl=wl,\n",
" sxt={'voltage': voltage},\n",
" )\n",
" plt.plot(wl * 1e3, abs(S[\"o1\", \"o2\"]) ** 2, label=str(voltage))\n",
" plt.xlabel(\"λ [nm]\")\n",
" plt.ylabel(\"T\")\n",
" plt.ylim(-0.05, 1.05)\n",
" plt.grid(True)\n",
" \n",
"plt.title('MZI vs voltage')\n",
"plt.legend()"
]
},
{
"cell_type": "markdown",
"id": "ceffc432-a4b8-46f6-a21c-61cf788c21ec",
Expand Down
17 changes: 14 additions & 3 deletions gdsfactory/component.py
Expand Up @@ -897,17 +897,28 @@ def plot(self, plotter: Optional[Plotter] = None, **kwargs) -> None:
Args:
plotter: backend ('holoviews', 'matplotlib', 'qt').

KeyError Args:
Keyword Args:
show_ports: Sets whether ports are drawn.
show_subports: Sets whether subports (ports that belong to references) are drawn.
label_aliases: Sets whether aliases are labeled with a text name.
new_window: If True, each call to quickplot() will generate a separate window.
blocking: If True, calling quickplot() will pause execution of ("block") the
remainder of the python code until the quickplot() window is closed.
If False, the window will be opened and code will continue to run.
zoom_factor: Sets the scaling factor when zooming the quickplot window with the
mousewheel/trackpad.
interactive_zoom: Enables using mousewheel/trackpad to zoom.
fontsize: for labels.
layers_excluded: list of layers to exclude.
layer_colors: layer_colors colors loaded from Klayout.
min_aspect: minimum aspect ratio.
"""
plotter = plotter or CONF.get("plotter", "matplotlib")

if plotter == "matplotlib":
from gdsfactory.quickplotter import quickplot as plot
from gdsfactory.quickplotter import quickplot

return plot(self)
return quickplot(self, **kwargs)
elif plotter == "holoviews":
try:
import holoviews as hv
Expand Down