import%20marimo%0A%0A__generated_with%20%3D%20%220.18.4%22%0Aapp%20%3D%20marimo.App()%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%20%20%20%20return%20(mo%2C)%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20from%20_notebook_template%20import%20inject_css%0A%0A%20%20%20%20inject_css(mo)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20from%20_notebook_template%20import%20make_doc_helpers%0A%0A%20%20%20%20doc_badges%2C%20doc_callout_html%2C%20doc_callout_list%20%3D%20make_doc_helpers(mo)%0A%20%20%20%20return%20doc_badges%2C%20doc_callout_html%2C%20doc_callout_list%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20from%20_notebook_template%20import%20make_section_tabs%0A%0A%20%20%20%20section_tabs%2C%20view_state%2C%20set_view%20%3D%20make_section_tabs(%0A%20%20%20%20%20%20%20%20mo%2C%0A%20%20%20%20%20%20%20%20options%3D(%22All%22%2C%20%22Overview%22%2C%20%22Targets%22%2C%20%22KLayout%20%2B%20PDK%22%2C%20%22Layout%20skeleton%22%2C%20%22Submission%22)%2C%0A%20%20%20%20%20%20%20%20value%3D%22All%22%2C%0A%20%20%20%20)%0A%20%20%20%20section_tabs%0A%20%20%20%20return%20set_view%2C%20view_state%0A%0A%0A%40app.cell%0Adef%20_(view_state)%3A%0A%20%20%20%20view%20%3D%20view_state()%0A%20%20%20%20show_overview%20%3D%20view%20in%20%5B%22All%22%2C%20%22Overview%22%5D%0A%20%20%20%20show_targets%20%3D%20view%20in%20%5B%22All%22%2C%20%22Targets%22%5D%0A%20%20%20%20show_klayout%20%3D%20view%20in%20%5B%22All%22%2C%20%22KLayout%20%2B%20PDK%22%5D%0A%20%20%20%20show_skeleton%20%3D%20view%20in%20%5B%22All%22%2C%20%22Layout%20skeleton%22%5D%0A%20%20%20%20show_submission%20%3D%20view%20in%20%5B%22All%22%2C%20%22Submission%22%5D%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20show_klayout%2C%0A%20%20%20%20%20%20%20%20show_overview%2C%0A%20%20%20%20%20%20%20%20show_skeleton%2C%0A%20%20%20%20%20%20%20%20show_submission%2C%0A%20%20%20%20%20%20%20%20show_targets%2C%0A%20%20%20%20%20%20%20%20view%2C%0A%20%20%20%20)%0A%0A%0A%40app.cell%0Adef%20_(doc_badges%2C%20view)%3A%0A%20%20%20%20doc_badges(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20f%22Notebook%20view%3A%20%3Cstrong%3E%7Bview%7D%3C%2Fstrong%3E%22%2C%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo%2C%20show_overview)%3A%0A%20%20%20%20mo.stop(not%20show_overview)%0A%20%20%20%20from%20_style%20import%20header%0A%0A%20%20%20%20header(%0A%20%20%20%20%20%20%20%20mo%2C%0A%20%20%20%20%20%20%20%20title%3D%22PDK%20MZI%20layout%20(KLayout%20%2B%20SiEPIC)%22%2C%0A%20%20%20%20%20%20%20%20subtitle%3D(%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Build%20a%20first%20MZI%20layout%20using%20the%20SiEPIC-EBeam%20PDK%20workflow%20in%20KLayout.%20%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Use%20modelling%20targets%20(%CE%94L%20%E2%86%94%20FSR)%20to%20guide%20geometry%20choices%2C%20then%20save%20your%20work%20in%20the%20openEBL%20repo.%22%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20badges%3D%5B%22Week%202%22%2C%20%22Lab%20companion%22%2C%20%22PDK%22%2C%20%22KLayout%22%2C%20%22openEBL%20workflow%22%5D%2C%0A%20%20%20%20%20%20%20%20toc%3D%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20(%22Overview%22%2C%20%22overview%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(%22Targets%22%2C%20%22targets%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(%22KLayout%20%2B%20PDK%22%2C%20%22klayout%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(%22Layout%20skeleton%22%2C%20%22skeleton%22)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(%22Submission%22%2C%20%22submission%22)%2C%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20build%3D%222025-12-16%22%2C%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(doc_callout_list%2C%20mo%2C%20show_overview)%3A%0A%20%20%20%20mo.stop(not%20show_overview)%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%3Ca%20id%3D%22overview%22%3E%3C%2Fa%3E%0A%20%20%20%20%23%23%20Overview%0A%0A%20%20%20%20This%20is%20the%20**PDK%20%2B%20compact-model%20%2B%20layout**%20companion%20for%20Week%202.%20The%20modelling%20companion%20is%3A%0A%20%20%20%20%60marimo_course%2Flessons%2Fw02_mzi_modelling.py%60%2C%20where%20you%20derived%20and%20explored%20the%20ideal%20MZI%20transfer%20function.%0A%0A%20%20%20%20In%20this%20notebook%2C%20you%E2%80%99ll%20connect%20three%20ideas%20that%20show%20up%20in%20every%20photonics%20workflow%3A%0A%0A%20%20%20%20-%20**Compact%20models%3A**%20fast%2C%20circuit-level%20models%20of%20components%20(couplers%2C%20waveguides%2C%20phase%20shifters)%20that%20let%20you%0A%20%20%20%20%20%20simulate%20a%20whole%20photonic%20circuit%20without%20solving%20Maxwell%E2%80%99s%20equations%20everywhere.%0A%20%20%20%20-%20**PDK%20(process%20design%20kit)%3A**%20a%20foundry%2Ftechnology%20%E2%80%9Cpackage%E2%80%9D%20that%20defines%20the%20**design%20rules**%2C%20**layers**%2C%20and%0A%20%20%20%20%20%20**parameterized%20building%20blocks**%20(plus%20their%20compact%20models)%20so%20your%20design%20is%20manufacturable%20and%20checkable.%0A%20%20%20%20-%20**Reproducibility%20across%20views%3A**%20build%20the%20*same*%20MZI%20you%20modelled%20last%20lesson%2C%20first%20as%20a%20**circuit**%20from%20compact%0A%20%20%20%20%20%20models%20and%20then%20as%20a%20**layout**%20in%20KLayout%20using%20PDK%20cells.%0A%0A%20%20%20%20In%20lab%2C%20you%20will%3A%0A%0A%20%20%20%201.%20Decide%20on%20a%20**target**%20(FSR%20%E2%86%92%20%CE%94L)%20near%20**1550%20nm**.%0A%20%20%20%202.%20Build%20an%20MZI%20from%20**compact%20models**%20(component%20%E2%86%92%20circuit)%20and%20sanity-check%20it%20against%20the%20Week%202%20model.%0A%20%20%20%203.%20Assemble%20the%20same%20MZI%20from%20**PDK%20building%20blocks**%20in%20KLayout%20(splitter%2C%20waveguides%2C%20combiner%2C%20I%2FO).%0A%20%20%20%204.%20Add%20the%20**conventions**%20required%20for%20downstream%20checks%20(ports%2Fpins%2C%20DevRec%2C%20labels%2Ffloorplan%20as%20required).%0A%20%20%20%205.%20Save%20your%20design%20in%20the%20**openEBL**%20submission%20repo%20and%20keep%20CI%20green.%0A%20%20%20%20%22%22%22)%0A%0A%20%20%20%20doc_callout_list(%0A%20%20%20%20%20%20%20%20%22info%22%2C%0A%20%20%20%20%20%20%20%20tag%3D%22Learning%20goals%22%2C%0A%20%20%20%20%20%20%20%20title%3D%22What%20you%20should%20be%20able%20to%20do%20after%20this%20notebook%22%2C%0A%20%20%20%20%20%20%20%20items%3D%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Explain%20what%20a%20compact%20model%20is%20and%20why%20we%20use%20them%20for%20circuit-level%20photonics%20design.%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Describe%20what%20a%20PDK%20provides%20(layers%2C%20rules%2C%20cells%2C%20models)%20and%20why%20it%20matters%20for%20manufacturable%20layouts.%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Create%20an%20MZI%20from%20compact-model%20building%20blocks%20and%20connect%20%CE%94L%20%E2%86%94%20FSR%20back%20to%20the%20modelling%20notebook.%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Implement%20the%20same%20MZI%20in%20KLayout%20using%20PDK-accurate%20cells%20so%20it%20passes%20downstream%20checks.%22%2C%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20)%0A%0A%20%20%20%20doc_callout_list(%0A%20%20%20%20%20%20%20%20%22warning%22%2C%0A%20%20%20%20%20%20%20%20tag%3D%22Where%20is%20the%20graded%20work%3F%22%2C%0A%20%20%20%20%20%20%20%20title%3D%22Lab%20companion%20vs%20homework%22%2C%0A%20%20%20%20%20%20%20%20items%3D%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22This%20notebook%20is%20a%20lab%20companion%20(workflow%20%2B%20checklists%20%2B%20reference).%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Graded%20work%20should%20live%20in%20a%20homework%20notebook%20under%20%60marimo_course%2Fassignments%2F%60.%22%2C%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo%2C%20show_overview)%3A%0A%20%20%20%20mo.stop(not%20show_overview)%0A%20%20%20%20klayout_open%20%3D%20mo.ui.checkbox(label%3D%22KLayout%20open%20with%20SiEPIC-EBeam%20PDK%22%2C%20value%3DFalse)%0A%20%20%20%20placed_blocks%20%3D%20mo.ui.checkbox(label%3D%22Placed%20I%2FO%20%2B%20splitter%2Fcombiner%20cells%22%2C%20value%3DFalse)%0A%20%20%20%20routed%20%3D%20mo.ui.checkbox(label%3D%22Routed%20an%20MZI%20skeleton%20with%20%CE%94L%22%2C%20value%3DFalse)%0A%20%20%20%20annotated%20%3D%20mo.ui.checkbox(label%3D%22Added%20pins%2FDevRec%2Flabels%20as%20required%22%2C%20value%3DFalse)%0A%20%20%20%20saved%20%3D%20mo.ui.checkbox(label%3D%22Saved%20in%20openEBL%20repo%20%2B%20CI%20checked%22%2C%20value%3DFalse)%0A%20%20%20%20mo.vstack(%5Bklayout_open%2C%20placed_blocks%2C%20routed%2C%20annotated%2C%20saved%5D)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo%2C%20set_view%2C%20show_overview)%3A%0A%20%20%20%20mo.stop(not%20show_overview)%0A%20%20%20%20go_targets%20%3D%20mo.ui.button(%0A%20%20%20%20%20%20%20%20value%3D0%2C%0A%20%20%20%20%20%20%20%20kind%3D%22success%22%2C%0A%20%20%20%20%20%20%20%20label%3D%22Go%20to%20Targets%22%2C%0A%20%20%20%20%20%20%20%20on_click%3Dlambda%20v%3A%20(set_view(%22Targets%22)%2C%20(v%20or%200)%20%2B%201)%5B-1%5D%2C%0A%20%20%20%20)%0A%20%20%20%20go_klayout%20%3D%20mo.ui.button(%0A%20%20%20%20%20%20%20%20value%3D0%2C%0A%20%20%20%20%20%20%20%20kind%3D%22neutral%22%2C%0A%20%20%20%20%20%20%20%20label%3D%22Go%20to%20KLayout%20%2B%20PDK%22%2C%0A%20%20%20%20%20%20%20%20on_click%3Dlambda%20v%3A%20(set_view(%22KLayout%20%2B%20PDK%22)%2C%20(v%20or%200)%20%2B%201)%5B-1%5D%2C%0A%20%20%20%20)%0A%20%20%20%20go_skeleton%20%3D%20mo.ui.button(%0A%20%20%20%20%20%20%20%20value%3D0%2C%0A%20%20%20%20%20%20%20%20kind%3D%22neutral%22%2C%0A%20%20%20%20%20%20%20%20label%3D%22Go%20to%20Layout%20skeleton%22%2C%0A%20%20%20%20%20%20%20%20on_click%3Dlambda%20v%3A%20(set_view(%22Layout%20skeleton%22)%2C%20(v%20or%200)%20%2B%201)%5B-1%5D%2C%0A%20%20%20%20)%0A%20%20%20%20go_submission%20%3D%20mo.ui.button(%0A%20%20%20%20%20%20%20%20value%3D0%2C%0A%20%20%20%20%20%20%20%20kind%3D%22neutral%22%2C%0A%20%20%20%20%20%20%20%20label%3D%22Go%20to%20Submission%22%2C%0A%20%20%20%20%20%20%20%20on_click%3Dlambda%20v%3A%20(set_view(%22Submission%22)%2C%20(v%20or%200)%20%2B%201)%5B-1%5D%2C%0A%20%20%20%20)%0A%20%20%20%20mo.hstack(%5Bgo_targets%2C%20go_klayout%2C%20go_skeleton%2C%20go_submission%5D%2C%20justify%3D%22start%22%2C%20gap%3D1)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(doc_callout_html%2C%20mo%2C%20show_targets)%3A%0A%20%20%20%20mo.stop(not%20show_targets)%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%3Ca%20id%3D%22targets%22%3E%3C%2Fa%3E%0A%20%20%20%20%23%23%20Targets%3A%20pick%20%CE%94L%20from%20an%20FSR%20target%20(1550%20nm%20default)%0A%0A%20%20%20%20Use%20the%20Week%202%20modelling%20notebook%20to%20build%20intuition%20and%20sanity-check%20values%3A%0A%20%20%20%20%60marimo_course%2Flessons%2Fw02_mzi_modelling.py%60.%0A%0A%20%20%20%20Rule-of-thumb%20near%20%CE%BB0%3A%0A%0A%20%20%20%20%24%24%0A%20%20%20%20%5Cmathrm%7BFSR%7D%20%5Capprox%20%5Cfrac%7B%5Clambda_0%5E2%7D%7Bn_g%5C%2C%5CDelta%20L%7D.%0A%20%20%20%20%24%24%0A%20%20%20%20%22%22%22)%0A%0A%20%20%20%20doc_callout_html(%0A%20%20%20%20%20%20%20%20%22info%22%2C%0A%20%20%20%20%20%20%20%20tag%3D%22Tip%22%2C%0A%20%20%20%20%20%20%20%20title%3D%22What%20matters%20for%20FSR%22%2C%0A%20%20%20%20%20%20%20%20html%3D(%0A%20%20%20%20%20%20%20%20%20%20%20%20%22-%20%CE%94L%20sets%20fringe%20spacing%20(FSR)%20approximately%20as%20%601%2F%CE%94L%60.%5Cn%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%22-%20Base%20length%20doesn%E2%80%99t%20change%20FSR%20in%20the%20ideal%20model.%5Cn%22%0A%20%20%20%20%20%20%20%20%20%20%20%20%22-%20Use%20**1550%20nm**%20by%20default%3B%20treat%20**1310%20nm**%20as%20an%20extension.%22%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo%2C%20show_targets)%3A%0A%20%20%20%20mo.stop(not%20show_targets)%0A%20%20%20%20wl0_nm%20%3D%20mo.ui.number(value%3D1550.0%2C%20label%3D%22%CE%BB0%20(nm)%22)%0A%20%20%20%20ng%20%3D%20mo.ui.number(value%3D4.19%2C%20label%3D%22ng%20(group%20index)%22)%0A%20%20%20%20deltaL_um%20%3D%20mo.ui.number(value%3D50.0%2C%20label%3D%22Planned%20%CE%94L%20(%C2%B5m)%22)%0A%20%20%20%20mo.hstack(%5Bwl0_nm%2C%20ng%2C%20deltaL_um%5D)%0A%20%20%20%20return%20deltaL_um%2C%20ng%2C%20wl0_nm%0A%0A%0A%40app.cell%0Adef%20_(deltaL_um%2C%20mo%2C%20ng%2C%20show_targets%2C%20wl0_nm)%3A%0A%20%20%20%20mo.stop(not%20show_targets)%0A%20%20%20%20wl0_um%20%3D%20float(wl0_nm.value)%20%2F%201e3%0A%20%20%20%20ng_val%20%3D%20float(ng.value)%0A%20%20%20%20delta_L_um%20%3D%20float(deltaL_um.value)%0A%20%20%20%20fsr_nm%20%3D%20(%0A%20%20%20%20%20%20%20%20None%0A%20%20%20%20%20%20%20%20if%20(delta_L_um%20%3C%3D%200%20or%20ng_val%20%3C%3D%200)%0A%20%20%20%20%20%20%20%20else%20(wl0_um%20*%20wl0_um)%20%2F%20(ng_val%20*%20delta_L_um)%20*%201e3%0A%20%20%20%20)%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20%22FSR%20estimate%3A%20(enter%20positive%20%CE%94L%20and%20ng)%22%0A%20%20%20%20%20%20%20%20if%20fsr_nm%20is%20None%0A%20%20%20%20%20%20%20%20else%20f%22FSR%20estimate%3A%20**%7Bfsr_nm%3A.2f%7D%20nm**%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(deltaL_um%2C%20mo%2C%20show_targets)%3A%0A%20%20%20%20mo.stop(not%20show_targets)%0A%20%20%20%20import%20base64%20as%20b64%0A%0A%20%20%20%20delta_L_um_vis%20%3D%20float(deltaL_um.value)%0A%20%20%20%20extra%20%3D%20max(0.0%2C%20min(80.0%2C%20delta_L_um_vis))%20%20%23%20purely%20visual%3B%20does%20not%20affect%20calculations%0A%20%20%20%20dy%20%3D%2026%0A%20%20%20%20x0%2C%20x1%2C%20x2%2C%20x3%20%3D%2020%2C%20110%2C%20310%2C%20400%0A%20%20%20%20y_mid%20%3D%2065%0A%20%20%20%20y_top%20%3D%20y_mid%20-%20dy%0A%20%20%20%20y_bot%20%3D%20y_mid%20%2B%20dy%0A%0A%20%20%20%20%23%20The%20upper%20arm%20is%20drawn%20a%20bit%20longer%20(extra)%20to%20visually%20suggest%20%CE%94L.%0A%20%20%20%20x2_top%20%3D%20x2%20%2B%20extra%0A%0A%20%20%20%20svg%20%3D%20f%22%22%22%0A%20%20%20%20%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22520%22%20height%3D%22140%22%20viewBox%3D%220%200%20520%20140%22%3E%0A%20%20%20%20%20%20%3Cstyle%3E%0A%20%20%20%20%20%20%20%20.wg%20%7B%7B%20fill%3A%20none%3B%20stroke%3A%20%23111%3B%20stroke-width%3A%203%3B%20stroke-linecap%3A%20round%3B%20stroke-linejoin%3A%20round%3B%20%7D%7D%0A%20%20%20%20%20%20%20%20.box%20%7B%7B%20fill%3A%20%23f6f6f6%3B%20stroke%3A%20%23999%3B%20stroke-width%3A%201.5%3B%20%7D%7D%0A%20%20%20%20%20%20%20%20.txt%20%7B%7B%20font-family%3A%20ui-sans-serif%2C%20system-ui%2C%20-apple-system%2C%20Segoe%20UI%2C%20Roboto%2C%20Helvetica%2C%20Arial%3B%20font-size%3A%2012px%3B%20fill%3A%20%23111%3B%20%7D%7D%0A%20%20%20%20%20%20%20%20.sub%20%7B%7B%20font-size%3A%2011px%3B%20fill%3A%20%23444%3B%20%7D%7D%0A%20%20%20%20%20%20%3C%2Fstyle%3E%0A%0A%20%20%20%20%20%20%3C!--%20input%20%2F%20output%20--%3E%0A%20%20%20%20%20%20%3Cpath%20class%3D%22wg%22%20d%3D%22M%20%7Bx0%7D%20%7By_mid%7D%20L%20%7Bx1%7D%20%7By_mid%7D%22%20%2F%3E%0A%20%20%20%20%20%20%3Cpath%20class%3D%22wg%22%20d%3D%22M%20%7Bx3%7D%20%7By_mid%7D%20L%20500%20%7By_mid%7D%22%20%2F%3E%0A%0A%20%20%20%20%20%20%3C!--%20coupler%20boxes%20--%3E%0A%20%20%20%20%20%20%3Crect%20class%3D%22box%22%20x%3D%22%7Bx1%7D%22%20y%3D%22%7By_mid-18%7D%22%20width%3D%2270%22%20height%3D%2236%22%20rx%3D%226%22%2F%3E%0A%20%20%20%20%20%20%3Crect%20class%3D%22box%22%20x%3D%22%7Bx3-70%7D%22%20y%3D%22%7By_mid-18%7D%22%20width%3D%2270%22%20height%3D%2236%22%20rx%3D%226%22%2F%3E%0A%20%20%20%20%20%20%3Ctext%20class%3D%22txt%22%20x%3D%22%7Bx1%2B10%7D%22%20y%3D%22%7By_mid-2%7D%22%3ESplitter%3C%2Ftext%3E%0A%20%20%20%20%20%20%3Ctext%20class%3D%22txt%22%20x%3D%22%7Bx3-60%7D%22%20y%3D%22%7By_mid-2%7D%22%3ECombiner%3C%2Ftext%3E%0A%0A%20%20%20%20%20%20%3C!--%20arms%20--%3E%0A%20%20%20%20%20%20%3Cpath%20class%3D%22wg%22%20d%3D%22M%20%7Bx1%2B70%7D%20%7By_top%7D%20L%20%7Bx2_top%7D%20%7By_top%7D%20L%20%7Bx3-70%7D%20%7By_top%7D%22%20%2F%3E%0A%20%20%20%20%20%20%3Cpath%20class%3D%22wg%22%20d%3D%22M%20%7Bx1%2B70%7D%20%7By_bot%7D%20L%20%7Bx2%7D%20%7By_bot%7D%20L%20%7Bx3-70%7D%20%7By_bot%7D%22%20%2F%3E%0A%20%20%20%20%20%20%3Cpath%20class%3D%22wg%22%20d%3D%22M%20%7Bx1%2B70%7D%20%7By_mid%7D%20L%20%7Bx1%2B70%7D%20%7By_top%7D%22%20%2F%3E%0A%20%20%20%20%20%20%3Cpath%20class%3D%22wg%22%20d%3D%22M%20%7Bx1%2B70%7D%20%7By_mid%7D%20L%20%7Bx1%2B70%7D%20%7By_bot%7D%22%20%2F%3E%0A%20%20%20%20%20%20%3Cpath%20class%3D%22wg%22%20d%3D%22M%20%7Bx3-70%7D%20%7By_mid%7D%20L%20%7Bx3-70%7D%20%7By_top%7D%22%20%2F%3E%0A%20%20%20%20%20%20%3Cpath%20class%3D%22wg%22%20d%3D%22M%20%7Bx3-70%7D%20%7By_mid%7D%20L%20%7Bx3-70%7D%20%7By_bot%7D%22%20%2F%3E%0A%0A%20%20%20%20%20%20%3C!--%20labels%20--%3E%0A%20%20%20%20%20%20%3Ctext%20class%3D%22txt%22%20x%3D%2220%22%20y%3D%2220%22%3ECircuit%20schematic%20(conceptual)%3C%2Ftext%3E%0A%20%20%20%20%20%20%3Ctext%20class%3D%22txt%20sub%22%20x%3D%2220%22%20y%3D%2238%22%3EUpper%20arm%20longer%20by%20%CE%94L%20%E2%89%88%20%7Bdelta_L_um_vis%3A.1f%7D%20%C2%B5m%20(visual%20only)%3C%2Ftext%3E%0A%20%20%20%20%3C%2Fsvg%3E%0A%20%20%20%20%22%22%22.strip()%0A%0A%20%20%20%20svg_b64%20%3D%20b64.b64encode(svg.encode(%22utf-8%22)).decode(%22ascii%22)%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20%22%3Cdiv%20style%3D'max-width%3A100%25%3B%20overflow%3Aauto%3B'%3E%22%0A%20%20%20%20%20%20%20%20f%22%3Cimg%20src%3D'data%3Aimage%2Fsvg%2Bxml%3Bbase64%2C%7Bsvg_b64%7D'%20style%3D'max-width%3A100%25%3B%20height%3Aauto%3B'%2F%3E%22%0A%20%20%20%20%20%20%20%20%22%3C%2Fdiv%3E%22%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(doc_callout_list%2C%20mo%2C%20show_klayout)%3A%0A%20%20%20%20mo.stop(not%20show_klayout)%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%3Ca%20id%3D%22klayout%22%3E%3C%2Fa%3E%0A%20%20%20%20%23%23%20KLayout%20%2B%20SiEPIC-EBeam%20PDK%20setup%0A%0A%20%20%20%20This%20section%20is%20intentionally%20procedural%3A%20the%20goal%20is%20to%20reduce%20%E2%80%9Cwhere%20do%20I%20click%3F%E2%80%9D%20friction%20in%20lab.%0A%20%20%20%20%22%22%22)%0A%0A%20%20%20%20doc_callout_list(%0A%20%20%20%20%20%20%20%20%22info%22%2C%0A%20%20%20%20%20%20%20%20tag%3D%22Checklist%22%2C%0A%20%20%20%20%20%20%20%20title%3D%22Setup%20and%20sanity%20checks%22%2C%0A%20%20%20%20%20%20%20%20ordered%3DTrue%2C%0A%20%20%20%20%20%20%20%20items%3D%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Install%20KLayout%20and%20the%20SiEPIC-EBeam%20PDK%20(confirm%20the%20technology%20loads).%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Confirm%20the%20correct%20process%2Frun%20assumptions%20for%20this%20semester%20(default%3A%20**1550%20nm**%20structures).%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Open%20an%20example%20layout%20from%20the%20PDK%20and%20verify%20layers%20look%20sensible.%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Create%20a%20new%20layout%20inside%20the%20run%20repo%20using%20the%20required%20filename%20conventions.%22%2C%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(doc_callout_list%2C%20mo%2C%20show_skeleton)%3A%0A%20%20%20%20mo.stop(not%20show_skeleton)%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%3Ca%20id%3D%22skeleton%22%3E%3C%2Fa%3E%0A%20%20%20%20%23%23%20Layout%20skeleton%20(MZI)%20%E2%80%94%20build%20first%2C%20refine%20later%0A%0A%20%20%20%20Build%20a%20simple%20MZI%20skeleton%20using%20PDK%20cells%20(splitter%2Fcombiner%20%2B%20waveguides%20%2B%20I%2FO).%0A%20%20%20%20Keep%20it%20**simple%20and%20clean**%3A%20symmetry%2C%20straight%20segments%20where%20possible%2C%20and%20a%20clear%20way%20to%20implement%20%CE%94L.%0A%0A%20%20%20%20Optional%3A%20generate%20a%20quick%20%E2%80%9Cgeometry-only%E2%80%9D%20MZI%20skeleton%20using%20gdsfactory%20to%20visualize%20the%20idea%2C%0A%20%20%20%20then%20recreate%20it%20with%20PDK-accurate%20cells%20in%20KLayout.%0A%20%20%20%20%22%22%22)%0A%0A%20%20%20%20doc_callout_list(%0A%20%20%20%20%20%20%20%20%22warning%22%2C%0A%20%20%20%20%20%20%20%20tag%3D%22Important%22%2C%0A%20%20%20%20%20%20%20%20title%3D%22PDK%20vs%20generic%20geometry%22%2C%0A%20%20%20%20%20%20%20%20items%3D%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22For%20openEBL%20submissions%2C%20your%20final%20design%20must%20follow%20the%20PDK%20cell%20conventions%20expected%20by%20the%20run%20repo.%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22A%20gdsfactory%20skeleton%20is%20useful%20for%20intuition%2C%20but%20it%20is%20not%20a%20substitute%20for%20a%20PDK-accurate%20KLayout%20design.%22%2C%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo%2C%20show_skeleton)%3A%0A%20%20%20%20mo.stop(not%20show_skeleton)%0A%20%20%20%20from%20_notebook_template%20import%20optional_import%0A%0A%20%20%20%20gf_mod%2C%20gf_error%20%3D%20optional_import(%22gdsfactory%22)%0A%20%20%20%20available%20%3D%20gf_mod%20is%20not%20None%0A%0A%20%20%20%20doc%20%3D%20(%0A%20%20%20%20%20%20%20%20%22Optional%20gdsfactory%20helper%3A%20**available**%22%0A%20%20%20%20%20%20%20%20if%20available%0A%20%20%20%20%20%20%20%20else%20f%22Optional%20gdsfactory%20helper%3A%20**not%20available**%20(%60%7Bgf_error%7D%60)%22%0A%20%20%20%20)%0A%20%20%20%20mo.md(doc)%0A%20%20%20%20return%20available%2C%20gf_mod%0A%0A%0A%40app.cell%0Adef%20_(available%2C%20mo%2C%20show_skeleton)%3A%0A%20%20%20%20mo.stop(not%20show_skeleton)%0A%20%20%20%20mo.stop(not%20available)%0A%0A%20%20%20%20gds_out%20%3D%20mo.ui.text(value%3D%22marimo_course%2Fbuild%2Fweek2_mzi_skeleton.gds%22%2C%20label%3D%22GDS%20output%20path%22)%0A%20%20%20%20delta_length%20%3D%20mo.ui.number(value%3D50.0%2C%20label%3D%22%CE%94L%20(%C2%B5m)%22)%0A%20%20%20%20length_x%20%3D%20mo.ui.number(value%3D60.0%2C%20label%3D%22length_x%20(%C2%B5m)%22)%0A%20%20%20%20length_y%20%3D%20mo.ui.number(value%3D10.0%2C%20label%3D%22length_y%20(%C2%B5m)%22)%0A%20%20%20%20write%20%3D%20mo.ui.button(value%3D0%2C%20label%3D%22Write%20GDS%22%2C%20kind%3D%22success%22%2C%20on_click%3Dlambda%20v%3A%20(v%20or%200)%20%2B%201)%0A%20%20%20%20mo.vstack(%5Bmo.hstack(%5Bgds_out%2C%20write%5D)%2C%20mo.hstack(%5Bdelta_length%2C%20length_x%2C%20length_y%5D)%5D)%0A%20%20%20%20return%20delta_length%2C%20gds_out%2C%20length_x%2C%20length_y%2C%20write%0A%0A%0A%40app.cell%0Adef%20_(available%2C%20gf_mod%2C%20mo%2C%20show_skeleton)%3A%0A%20%20%20%20mo.stop(not%20show_skeleton)%0A%20%20%20%20mo.stop(not%20available)%0A%0A%20%20%20%20from%20pathlib%20import%20Path%0A%0A%20%20%20%20def%20write_mzi_skeleton(*%2C%20out%3A%20Path%2C%20delta_length_um%3A%20float%2C%20length_x_um%3A%20float%2C%20length_y_um%3A%20float)%20-%3E%20Path%3A%0A%20%20%20%20%20%20%20%20gf%20%3D%20gf_mod%0A%20%20%20%20%20%20%20%20mzi%20%3D%20gf.components.mzi(%0A%20%20%20%20%20%20%20%20%20%20%20%20delta_length%3Dfloat(delta_length_um)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20length_x%3Dfloat(length_x_um)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20length_y%3Dfloat(length_y_um)%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20out.parent.mkdir(parents%3DTrue%2C%20exist_ok%3DTrue)%0A%20%20%20%20%20%20%20%20written%20%3D%20mzi.write_gds(gdspath%3Dout)%0A%20%20%20%20%20%20%20%20return%20Path(written)%0A%20%20%20%20return%20Path%2C%20write_mzi_skeleton%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20Path%2C%0A%20%20%20%20available%2C%0A%20%20%20%20delta_length%2C%0A%20%20%20%20gds_out%2C%0A%20%20%20%20length_x%2C%0A%20%20%20%20length_y%2C%0A%20%20%20%20mo%2C%0A%20%20%20%20show_skeleton%2C%0A%20%20%20%20write%2C%0A%20%20%20%20write_mzi_skeleton%2C%0A)%3A%0A%20%20%20%20mo.stop(not%20show_skeleton)%0A%20%20%20%20mo.stop(not%20available)%0A%0A%20%20%20%20blocks%20%3D%20%5B%5D%0A%20%20%20%20if%20int(write.value%20or%200)%20%3C%3D%200%3A%0A%20%20%20%20%20%20%20%20blocks.append(%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.md(%22Click%20**Write%20GDS**%20to%20export%20a%20skeleton%20you%20can%20inspect%20in%20KLayout.%22)%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20out%20%3D%20Path(str(gds_out.value)).expanduser()%0A%20%20%20%20%20%20%20%20try%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20written%20%3D%20write_mzi_skeleton(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20out%3Dout%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20delta_length_um%3Dfloat(delta_length.value)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20length_x_um%3Dfloat(length_x.value)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20length_y_um%3Dfloat(length_y.value)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20blocks.append(mo.md(f%22Wrote%3A%20%60%7Bwritten%7D%60%22))%0A%20%20%20%20%20%20%20%20%20%20%20%20blocks.append(mo.md(f%22Open%20in%20KLayout%3A%20%60klayout%20%7Bwritten%7D%60%22))%0A%20%20%20%20%20%20%20%20except%20Exception%20as%20e%3A%20%20%23%20pragma%3A%20no%20cover%0A%20%20%20%20%20%20%20%20%20%20%20%20blocks.append(mo.md(f%22(GDS%20write%20failed%3A%20%60%7Btype(e).__name__%7D%3A%20%7Be%7D%60)%22))%0A%0A%20%20%20%20mo.vstack(blocks)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(doc_callout_list%2C%20mo%2C%20show_submission)%3A%0A%20%20%20%20mo.stop(not%20show_submission)%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%3Ca%20id%3D%22submission%22%3E%3C%2Fa%3E%0A%20%20%20%20%23%23%20Save%20%2B%20submission%20workflow%20(openEBL)%0A%0A%20%20%20%20The%20details%20depend%20on%20the%20specific%20openEBL%20run%20repository%20used%20this%20semester%2C%20but%20the%20structure%20is%20consistent%3A%0A%20%20%20%20save%20designs%20in%20the%20right%20folder%2C%20run%20checks%2C%20fix%20failures%2C%20and%20submit%20via%20PR.%0A%20%20%20%20%22%22%22)%0A%0A%20%20%20%20doc_callout_list(%0A%20%20%20%20%20%20%20%20%22info%22%2C%0A%20%20%20%20%20%20%20%20tag%3D%22Checklist%22%2C%0A%20%20%20%20%20%20%20%20title%3D%22Before%20you%20push%22%2C%0A%20%20%20%20%20%20%20%20ordered%3DTrue%2C%0A%20%20%20%20%20%20%20%20items%3D%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Confirm%20your%20layout%20file%20is%20inside%20the%20run%20repo%20(e.g.%2C%20%60openEBL-2026-02%2Fsubmissions%2F...%60).%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Verify%20naming%20conventions%20and%20top-level%20cell%20structure%20match%20the%20run%20instructions.%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Run%20local%20verification%20in%20KLayout%20if%20available%20(press%20V%20%2F%20run%20scripts).%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Push%20to%20your%20fork%20and%20check%20GitHub%20Actions%20results%3B%20download%20artifacts%20when%20something%20fails.%22%2C%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
7506f3c9283ad9a8b4c38db5ff2b42d3